зеркало из https://github.com/dotnet/sdk.git
Merge branch 'release/7.0.4xx'
This commit is contained in:
Коммит
df5018d939
|
@ -20,7 +20,6 @@
|
|||
"src\\Cli\\Microsoft.TemplateEngine.Cli\\Microsoft.TemplateEngine.Cli.csproj",
|
||||
"src\\Cli\\dotnet\\dotnet.csproj",
|
||||
"src\\Containers\\Microsoft.NET.Build.Containers\\Microsoft.NET.Build.Containers.csproj",
|
||||
"src\\Containers\\containerize\\containerize.csproj",
|
||||
"src\\Containers\\packaging\\package.csproj",
|
||||
"src\\Layout\\redist\\redist.csproj",
|
||||
"src\\Layout\\tool_fsharp\\tool_fsc.csproj",
|
||||
|
|
|
@ -463,30 +463,9 @@ namespace Microsoft.DotNet.Workloads.Workload.Install
|
|||
throw new ArgumentException(string.Format(LocalizableStrings.RollbackDefinitionFileDoesNotExist, rollbackDefinitionFilePath));
|
||||
}
|
||||
}
|
||||
return JsonSerializer.Deserialize<IDictionary<string, string>>(fileContent)
|
||||
.Select(manifest =>
|
||||
{
|
||||
ManifestVersion manifestVersion;
|
||||
SdkFeatureBand manifestFeatureBand;
|
||||
var parts = manifest.Value.Split('/');
|
||||
|
||||
string manifestVersionString = (parts[0]);
|
||||
if (!FXVersion.TryParse(manifestVersionString, out FXVersion version))
|
||||
{
|
||||
throw new FormatException(String.Format(LocalizableStrings.InvalidVersionForWorkload, manifest.Key, manifestVersionString));
|
||||
}
|
||||
|
||||
manifestVersion = new ManifestVersion(parts[0]);
|
||||
if (parts.Length == 1)
|
||||
{
|
||||
manifestFeatureBand = _sdkFeatureBand;
|
||||
}
|
||||
else
|
||||
{
|
||||
manifestFeatureBand = new SdkFeatureBand(parts[1]);
|
||||
}
|
||||
return (new ManifestId(manifest.Key), manifestVersion, manifestFeatureBand);
|
||||
});
|
||||
return WorkloadSet.FromJson(fileContent, _sdkFeatureBand).ManifestVersions
|
||||
.Select(kvp => (kvp.Key, kvp.Value.Version, kvp.Value.FeatureBand));
|
||||
}
|
||||
|
||||
private bool BackgroundUpdatesAreDisabled() =>
|
||||
|
|
|
@ -90,10 +90,10 @@ namespace Microsoft.DotNet.Workloads.Workload.Update
|
|||
}
|
||||
else if (_printRollbackDefinitionOnly)
|
||||
{
|
||||
var manifests = _workloadResolver.GetInstalledManifests().ToDictionary(m => m.Id, m => m.Version + "/" + m.ManifestFeatureBand, StringComparer.OrdinalIgnoreCase);
|
||||
var workloadSet = WorkloadSet.FromManifests(_workloadResolver.GetInstalledManifests());
|
||||
|
||||
Reporter.WriteLine("==workloadRollbackDefinitionJsonOutputStart==");
|
||||
Reporter.WriteLine(JsonSerializer.Serialize(manifests, new JsonSerializerOptions() { WriteIndented = true }));
|
||||
Reporter.WriteLine(workloadSet.ToJson());
|
||||
Reporter.WriteLine("==workloadRollbackDefinitionJsonOutputEnd==");
|
||||
}
|
||||
else
|
||||
|
|
|
@ -274,21 +274,21 @@ public static class ContainerHelpers
|
|||
/// <summary>
|
||||
/// Checks if a given container image name adheres to the image name spec. If not, and recoverable, then normalizes invalid characters.
|
||||
/// </summary>
|
||||
internal static bool NormalizeImageName(string containerImageName,
|
||||
internal static bool NormalizeRepository(string containerRepository,
|
||||
[NotNullWhen(false)] out string? normalizedImageName)
|
||||
{
|
||||
if (IsValidImageName(containerImageName))
|
||||
if (IsValidImageName(containerRepository))
|
||||
{
|
||||
normalizedImageName = null;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Char.IsLetterOrDigit(containerImageName, 0))
|
||||
if (!Char.IsLetterOrDigit(containerRepository, 0))
|
||||
{
|
||||
throw new ArgumentException(Resources.Resource.GetString(nameof(Strings.InvalidImageName)));
|
||||
}
|
||||
var loweredImageName = containerImageName.ToLowerInvariant();
|
||||
var loweredImageName = containerRepository.ToLowerInvariant();
|
||||
normalizedImageName = imageNameCharacters.Replace(loweredImageName, "-");
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,9 @@ internal static class KnownStrings
|
|||
{
|
||||
public static readonly string ContainerBaseImage = nameof(ContainerBaseImage);
|
||||
public static readonly string ContainerRegistry = nameof(ContainerRegistry);
|
||||
/// <summary>Note that this is deprecated in favor of <see cref="ContainerRepository"/></summary>
|
||||
public static readonly string ContainerImageName = nameof(ContainerImageName);
|
||||
public static readonly string ContainerRepository = nameof(ContainerRepository);
|
||||
public static readonly string ContainerImageTag = nameof(ContainerImageTag);
|
||||
public static readonly string ContainerImageTags = nameof(ContainerImageTags);
|
||||
public static readonly string ContainerWorkingDirectory = nameof(ContainerWorkingDirectory);
|
||||
|
@ -33,6 +35,8 @@ internal static class KnownStrings
|
|||
|
||||
public static class ErrorCodes
|
||||
{
|
||||
public static readonly string CONTAINER002 = nameof(CONTAINER002);
|
||||
public static readonly string CONTAINER003 = nameof(CONTAINER003);
|
||||
public static readonly string CONTAINER1011 = nameof(CONTAINER1011);
|
||||
public static readonly string CONTAINER1012 = nameof(CONTAINER1012);
|
||||
public static readonly string CONTAINER1013 = nameof(CONTAINER1013);
|
||||
|
|
|
@ -137,7 +137,8 @@ internal record struct Layer
|
|||
|
||||
fs.Position = 0;
|
||||
|
||||
SHA256.HashData(fs, hash);
|
||||
int bW = SHA256.HashData(fs, hash);
|
||||
Debug.Assert(bW == hash.Length);
|
||||
|
||||
// Writes a tar entry corresponding to the file system item.
|
||||
static void WriteTarEntryForFile(TarWriter writer, FileSystemInfo file, string containerPath, IEnumerable<KeyValuePair<string, string>> entryAttributes)
|
||||
|
|
|
@ -95,4 +95,9 @@
|
|||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<!-- Copy to *.csproj for using in sanity checks integration tests. -->
|
||||
<Target Name="CopyCsprojToTestExecutionDirectory" AfterTargets="Build">
|
||||
<Copy SourceFiles="$(MSBuildThisFileFullPath)" DestinationFiles="$(ArtifactsTmpDir)Container\ProjectFiles\$(MSBuildThisFileName).csproj" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -47,8 +47,8 @@ Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GeneratedContainerConfigurat
|
|||
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GeneratedContainerConfiguration.set -> void
|
||||
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GeneratedContainerManifest.get -> string!
|
||||
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GeneratedContainerManifest.set -> void
|
||||
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ImageName.get -> string!
|
||||
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ImageName.set -> void
|
||||
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.Repository.get -> string!
|
||||
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.Repository.set -> void
|
||||
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ImageTags.get -> string![]!
|
||||
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ImageTags.set -> void
|
||||
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.Labels.get -> Microsoft.Build.Framework.ITaskItem![]!
|
||||
|
@ -71,8 +71,8 @@ override Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GetProcessStartInfo
|
|||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerEnvironmentVariables.get -> Microsoft.Build.Framework.ITaskItem![]!
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerEnvironmentVariables.set -> void
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerImageName.get -> string!
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerImageName.set -> void
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerRepository.get -> string!
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerRepository.set -> void
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerImageTag.get -> string!
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerImageTag.set -> void
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerImageTags.get -> string![]!
|
||||
|
@ -82,7 +82,7 @@ Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerRegistry.
|
|||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.FullyQualifiedBaseImageName.get -> string!
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.FullyQualifiedBaseImageName.set -> void
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.NewContainerEnvironmentVariables.get -> Microsoft.Build.Framework.ITaskItem![]!
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.NewContainerImageName.get -> string!
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.NewContainerRepository.get -> string!
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.NewContainerRegistry.get -> string!
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.NewContainerTags.get -> string![]!
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ParseContainerProperties() -> void
|
||||
|
|
|
@ -137,8 +137,8 @@ Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GeneratedContainerConfigurat
|
|||
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GeneratedContainerConfiguration.set -> void
|
||||
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GeneratedContainerManifest.get -> string!
|
||||
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GeneratedContainerManifest.set -> void
|
||||
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ImageName.get -> string!
|
||||
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ImageName.set -> void
|
||||
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.Repository.get -> string!
|
||||
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.Repository.set -> void
|
||||
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ImageTags.get -> string![]!
|
||||
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ImageTags.set -> void
|
||||
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.Labels.get -> Microsoft.Build.Framework.ITaskItem![]!
|
||||
|
@ -160,8 +160,8 @@ Microsoft.NET.Build.Containers.Tasks.CreateNewImage.WorkingDirectory.set -> void
|
|||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerEnvironmentVariables.get -> Microsoft.Build.Framework.ITaskItem![]!
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerEnvironmentVariables.set -> void
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerImageName.get -> string!
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerImageName.set -> void
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerRepository.get -> string!
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerRepository.set -> void
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerImageTag.get -> string!
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerImageTag.set -> void
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerImageTags.get -> string![]!
|
||||
|
@ -171,7 +171,7 @@ Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerRegistry.
|
|||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.FullyQualifiedBaseImageName.get -> string!
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.FullyQualifiedBaseImageName.set -> void
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.NewContainerEnvironmentVariables.get -> Microsoft.Build.Framework.ITaskItem![]!
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.NewContainerImageName.get -> string!
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.NewContainerRepository.get -> string!
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.NewContainerRegistry.get -> string!
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.NewContainerTags.get -> string![]!
|
||||
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ParseContainerProperties() -> void
|
||||
|
|
|
@ -421,7 +421,8 @@ internal sealed class Registry
|
|||
HttpResponseMessage patchResponse = await client.PatchAsync(uploadUri.Uri, content, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
if (patchResponse.StatusCode != HttpStatusCode.Accepted)
|
||||
// Fail the upload if the response code is not Accepted (202) or if uploading to Amazon ECR which returns back Created (201).
|
||||
if (!(patchResponse.StatusCode == HttpStatusCode.Accepted || (IsAmazonECRRegistry && patchResponse.StatusCode == HttpStatusCode.Created)))
|
||||
{
|
||||
var headers = patchResponse.Headers.ToString();
|
||||
var detail = await patchResponse.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
|
||||
namespace Microsoft.NET.Build.Containers.Resources {
|
||||
using System;
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
|
@ -23,15 +23,15 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Strings {
|
||||
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Strings() {
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
|
@ -45,7 +45,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
|
@ -59,7 +59,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER0000: Value for unit test {0}.
|
||||
/// </summary>
|
||||
|
@ -68,7 +68,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("_Test", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER1002: Request to Amazon Elastic Container Registry failed prematurely. This is often caused when the target repository does not exist in the registry..
|
||||
/// </summary>
|
||||
|
@ -77,7 +77,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("AmazonRegistryFailed", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER2008: Both {0} and {1} were provided, but only one or the other is allowed..
|
||||
/// </summary>
|
||||
|
@ -86,7 +86,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("AmbiguousTags", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER2009: Could not parse {0}: {1}.
|
||||
/// </summary>
|
||||
|
@ -95,7 +95,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("BaseImageNameParsingFailed", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER2013: {0} had spaces in it, replacing with dashes..
|
||||
/// </summary>
|
||||
|
@ -104,7 +104,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("BaseImageNameWithSpaces", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER2020: {0} does not specify a registry and will be pulled from Docker Hub. Please prefix the name with the image registry, for example: '{1}/<image>'..
|
||||
/// </summary>
|
||||
|
@ -122,7 +122,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("BaseImageNotFound", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER1001: Failed to upload blob to {0}; received {1} with detail {2}..
|
||||
/// </summary>
|
||||
|
@ -131,7 +131,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("BlobUploadFailed", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER1007: Could not deserialize token from JSON..
|
||||
/// </summary>
|
||||
|
@ -140,7 +140,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("CouldntDeserializeJsonToken", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER2012: Could not recognize registry '{0}'..
|
||||
/// </summary>
|
||||
|
@ -149,7 +149,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("CouldntRecognizeRegistry", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER3002: Failed to get docker info({0})\n{1}\n{2}.
|
||||
/// </summary>
|
||||
|
@ -158,7 +158,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("DockerInfoFailed", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER3002: Failed to get docker info: {0}.
|
||||
/// </summary>
|
||||
|
@ -167,7 +167,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("DockerInfoFailed_Ex", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER3001: Failed creating docker process..
|
||||
/// </summary>
|
||||
|
@ -176,7 +176,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("DockerProcessCreationFailed", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER4006: Property '{0}' is empty or contains whitespace and will be ignored..
|
||||
/// </summary>
|
||||
|
@ -185,7 +185,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("EmptyOrWhitespacePropertyIgnored", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER4004: Items '{0}' contain empty item(s) which will be ignored..
|
||||
/// </summary>
|
||||
|
@ -194,7 +194,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("EmptyValuesIgnored", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER1008: Failed retrieving credentials for "{0}": {1}.
|
||||
/// </summary>
|
||||
|
@ -203,7 +203,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("FailedRetrievingCredentials", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to No host object detected..
|
||||
/// </summary>
|
||||
|
@ -212,7 +212,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("HostObjectNotDetected", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER1009: Failed to load image to local registry. stdout: {0}.
|
||||
/// </summary>
|
||||
|
@ -221,7 +221,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("ImageLoadFailed", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER1010: Pulling images from local registry is not supported..
|
||||
/// </summary>
|
||||
|
@ -230,16 +230,16 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("ImagePullNotSupported", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER2014: Invalid {0}: {1}..
|
||||
/// </summary>
|
||||
internal static string InvalidContainerImageName {
|
||||
internal static string InvalidContainerRepository {
|
||||
get {
|
||||
return ResourceManager.GetString("InvalidContainerImageName", resourceCulture);
|
||||
return ResourceManager.GetString("InvalidContainerRepository", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER2015: {0}: '{1}' was not a valid Environment Variable. Ignoring..
|
||||
/// </summary>
|
||||
|
@ -248,7 +248,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("InvalidEnvVar", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER2005: The first character of the image name must be a lowercase letter or a digit..
|
||||
/// </summary>
|
||||
|
@ -257,7 +257,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("InvalidImageName", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER2017: A ContainerPort item was provided with an invalid port number '{0}'. ContainerPort items must have an Include value that is an integer, and a Type value that is either 'tcp' or 'udp'..
|
||||
/// </summary>
|
||||
|
@ -266,7 +266,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("InvalidPort_Number", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER2017: A ContainerPort item was provided with an invalid port number '{0}' and an invalid port type '{1}'. ContainerPort items must have an Include value that is an integer, and a Type value that is either 'tcp' or 'udp'..
|
||||
/// </summary>
|
||||
|
@ -275,7 +275,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("InvalidPort_NumberAndType", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER2017: A ContainerPort item was provided with an invalid port type '{0}'. ContainerPort items must have an Include value that is an integer, and a Type value that is either 'tcp' or 'udp'..
|
||||
/// </summary>
|
||||
|
@ -284,7 +284,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("InvalidPort_Type", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER2018: Invalid SDK prerelease version '{0}' - only 'rc' and 'preview' are supported..
|
||||
/// </summary>
|
||||
|
@ -293,7 +293,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("InvalidSdkPrereleaseVersion", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER2019: Invalid SDK semantic version '{0}'..
|
||||
/// </summary>
|
||||
|
@ -302,7 +302,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("InvalidSdkVersion", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER2007: Invalid {0} provided: {1}. Image tags must be alphanumeric, underscore, hyphen, or period..
|
||||
/// </summary>
|
||||
|
@ -311,7 +311,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("InvalidTag", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER2010: Invalid {0} provided: {1}. {0} must be a semicolon-delimited list of valid image tags. Image tags must be alphanumeric, underscore, hyphen, or period..
|
||||
/// </summary>
|
||||
|
@ -320,7 +320,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("InvalidTags", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER1003: Token response had neither token nor access_token..
|
||||
/// </summary>
|
||||
|
@ -329,7 +329,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("InvalidTokenResponse", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER4005: Item '{0}' contains items without metadata 'Value', and they will be ignored..
|
||||
/// </summary>
|
||||
|
@ -338,7 +338,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("ItemsWithoutMetadata", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER1012: The local registry is not available, but pushing to a local registry was requested.
|
||||
/// </summary>
|
||||
|
@ -347,7 +347,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("LocalRegistryNotAvailable", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER2004: Unable to download layer with descriptor '{0}' from registry '{1}' because it does not exist..
|
||||
/// </summary>
|
||||
|
@ -356,7 +356,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("MissingLinkToRegistry", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER2016: ContainerPort item '{0}' does not specify the port number. Please ensure the item's Include is a port number, for example '<ContainerPort Include="80" />'.
|
||||
/// </summary>
|
||||
|
@ -365,7 +365,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("MissingPortNumber", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER1004: No RequestUri specified..
|
||||
/// </summary>
|
||||
|
@ -374,7 +374,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("NoRequestUriSpecified", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to '{0}' was not a valid container image name, it was normalized to '{1}'.
|
||||
/// </summary>
|
||||
|
@ -383,7 +383,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("NormalizedContainerName", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER2011: {0} '{1}' does not exist.
|
||||
/// </summary>
|
||||
|
@ -392,7 +392,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("PublishDirectoryDoesntExist", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER1013: Failed to push to the output registry: {0}.
|
||||
/// </summary>
|
||||
|
@ -401,7 +401,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("RegistryOutputPushFailed", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER1005: Registry push failed..
|
||||
/// </summary>
|
||||
|
@ -410,7 +410,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("RegistryPushFailed", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER4003: Required '{0}' items contain empty items..
|
||||
/// </summary>
|
||||
|
@ -419,7 +419,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("RequiredItemsContainsEmptyItems", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER4002: Required '{0}' items were not set..
|
||||
/// </summary>
|
||||
|
@ -428,7 +428,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("RequiredItemsNotSet", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER4001: Required property '{0}' was not set or empty..
|
||||
/// </summary>
|
||||
|
@ -437,7 +437,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("RequiredPropertyNotSetOrEmpty", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER1006: Too many retries, stopping..
|
||||
/// </summary>
|
||||
|
@ -446,7 +446,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("TooManyRetries", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER2002: Unknown local registry type '{0}'. Valid local container registry types are {1}..
|
||||
/// </summary>
|
||||
|
@ -455,7 +455,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("UnknownLocalRegistryType", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER2003: The manifest for {0}:{1} from registry {2} was an unknown type: {3}. Please raise an issue at https://github.com/dotnet/sdk-container-builds/issues with this message..
|
||||
/// </summary>
|
||||
|
@ -464,7 +464,7 @@ namespace Microsoft.NET.Build.Containers.Resources {
|
|||
return ResourceManager.GetString("UnknownMediaType", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CONTAINER2001: Unrecognized mediaType '{0}'..
|
||||
/// </summary>
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
|
@ -26,36 +26,36 @@
|
|||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
|
@ -188,7 +188,7 @@
|
|||
<value>CONTAINER1009: Failed to load image from local registry. stdout: {0}</value>
|
||||
<comment>{StrBegin="CONTAINER1009: "}</comment>
|
||||
</data>
|
||||
<data name="InvalidContainerImageName" xml:space="preserve">
|
||||
<data name="InvalidContainerRepository" xml:space="preserve">
|
||||
<value>CONTAINER2014: Invalid {0}: {1}.</value>
|
||||
<comment>{StrBegin="CONTAINER2014: "}</comment>
|
||||
</data>
|
||||
|
@ -299,4 +299,4 @@
|
|||
<value>CONTAINER0000: Value for unit test {0}</value>
|
||||
<comment>Used only for unit tests</comment>
|
||||
</data>
|
||||
</root>
|
||||
</root>
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
<target state="new">CONTAINER1010: Pulling images from local registry is not supported.</target>
|
||||
<note>{StrBegin="CONTAINER1010: "}</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidContainerImageName">
|
||||
<trans-unit id="InvalidContainerRepository">
|
||||
<source>CONTAINER2014: Invalid {0}: {1}.</source>
|
||||
<target state="translated">CONTAINER2014: Neplatná {0}: {1}.</target>
|
||||
<note>{StrBegin="CONTAINER2014: "}</note>
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
<target state="new">CONTAINER1010: Pulling images from local registry is not supported.</target>
|
||||
<note>{StrBegin="CONTAINER1010: "}</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidContainerImageName">
|
||||
<trans-unit id="InvalidContainerRepository">
|
||||
<source>CONTAINER2014: Invalid {0}: {1}.</source>
|
||||
<target state="translated">CONTAINER2014: Ungültiger {0}: {1}.</target>
|
||||
<note>{StrBegin="CONTAINER2014: "}</note>
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
<target state="needs-review-translation">CONTAINER1010: No se admite la extracción de imágenes del demonio de Docker local.</target>
|
||||
<note>{StrBegin="CONTAINER1010: "}</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidContainerImageName">
|
||||
<trans-unit id="InvalidContainerRepository">
|
||||
<source>CONTAINER2014: Invalid {0}: {1}.</source>
|
||||
<target state="translated">CONTAINER2014: {0} no válido: {1}.</target>
|
||||
<note>{StrBegin="CONTAINER2014: "}</note>
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
<target state="new">CONTAINER1010: Pulling images from local registry is not supported.</target>
|
||||
<note>{StrBegin="CONTAINER1010: "}</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidContainerImageName">
|
||||
<trans-unit id="InvalidContainerRepository">
|
||||
<source>CONTAINER2014: Invalid {0}: {1}.</source>
|
||||
<target state="translated">CONTAINER2014: {0} non valide : {1}.</target>
|
||||
<note>{StrBegin="CONTAINER2014: "}</note>
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
<target state="new">CONTAINER1010: Pulling images from local registry is not supported.</target>
|
||||
<note>{StrBegin="CONTAINER1010: "}</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidContainerImageName">
|
||||
<trans-unit id="InvalidContainerRepository">
|
||||
<source>CONTAINER2014: Invalid {0}: {1}.</source>
|
||||
<target state="translated">CONTAINER2014: {0}non valido: {1}.</target>
|
||||
<note>{StrBegin="CONTAINER2014: "}</note>
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
<target state="needs-review-translation">CONTAINER1010: ローカル Docker デーモンからのイメージのプルはサポートされていません。</target>
|
||||
<note>{StrBegin="CONTAINER1010: "}</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidContainerImageName">
|
||||
<trans-unit id="InvalidContainerRepository">
|
||||
<source>CONTAINER2014: Invalid {0}: {1}.</source>
|
||||
<target state="translated">CONTAINER2014: 無効な {0}: {1}。</target>
|
||||
<note>{StrBegin="CONTAINER2014: "}</note>
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
<target state="needs-review-translation">CONTAINER1010: 로컬 Docker 디먼에서 이미지 끌어오기가 지원되지 않습니다.</target>
|
||||
<note>{StrBegin="CONTAINER1010: "}</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidContainerImageName">
|
||||
<trans-unit id="InvalidContainerRepository">
|
||||
<source>CONTAINER2014: Invalid {0}: {1}.</source>
|
||||
<target state="translated">CONTAINER2014: 잘못된 {0}: {1}.</target>
|
||||
<note>{StrBegin="CONTAINER2014: "}</note>
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
<target state="needs-review-translation">CONTAINER1010: ściąganie obrazów z lokalnego demona platformy Docker nie jest obsługiwane.</target>
|
||||
<note>{StrBegin="CONTAINER1010: "}</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidContainerImageName">
|
||||
<trans-unit id="InvalidContainerRepository">
|
||||
<source>CONTAINER2014: Invalid {0}: {1}.</source>
|
||||
<target state="translated">CONTAINER2014: Nieprawidłowy element {0}: {1}.</target>
|
||||
<note>{StrBegin="CONTAINER2014: "}</note>
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
<target state="needs-review-translation">CONTAINER1010: não há suporte para a extração de imagens do daemon do Docker local.</target>
|
||||
<note>{StrBegin="CONTAINER1010: "}</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidContainerImageName">
|
||||
<trans-unit id="InvalidContainerRepository">
|
||||
<source>CONTAINER2014: Invalid {0}: {1}.</source>
|
||||
<target state="translated">CONTAINER2014: Inválido {0}: {1}.</target>
|
||||
<note>{StrBegin="CONTAINER2014: "}</note>
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
<target state="needs-review-translation">CONTAINER1010: извлечение образов из локальной управляющей программы Docker не поддерживается.</target>
|
||||
<note>{StrBegin="CONTAINER1010: "}</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidContainerImageName">
|
||||
<trans-unit id="InvalidContainerRepository">
|
||||
<source>CONTAINER2014: Invalid {0}: {1}.</source>
|
||||
<target state="translated">CONTAINER2014: недопустимый {0}: {1}.</target>
|
||||
<note>{StrBegin="CONTAINER2014: "}</note>
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
<target state="new">CONTAINER1010: Pulling images from local registry is not supported.</target>
|
||||
<note>{StrBegin="CONTAINER1010: "}</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidContainerImageName">
|
||||
<trans-unit id="InvalidContainerRepository">
|
||||
<source>CONTAINER2014: Invalid {0}: {1}.</source>
|
||||
<target state="translated">CONTAINER2014: Geçersiz {0}: {1}.</target>
|
||||
<note>{StrBegin="CONTAINER2014: "}</note>
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
<target state="new">CONTAINER1010: Pulling images from local registry is not supported.</target>
|
||||
<note>{StrBegin="CONTAINER1010: "}</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidContainerImageName">
|
||||
<trans-unit id="InvalidContainerRepository">
|
||||
<source>CONTAINER2014: Invalid {0}: {1}.</source>
|
||||
<target state="translated">CONTAINER2014: 无效 {0}: {1}。</target>
|
||||
<note>{StrBegin="CONTAINER2014: "}</note>
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
<target state="needs-review-translation">CONTAINER1010: 不支援從本機 Docker 精靈提取映像。</target>
|
||||
<note>{StrBegin="CONTAINER1010: "}</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidContainerImageName">
|
||||
<trans-unit id="InvalidContainerRepository">
|
||||
<source>CONTAINER2014: Invalid {0}: {1}.</source>
|
||||
<target state="translated">CONTAINER2014: 無效的 {0}: {1}。</target>
|
||||
<note>{StrBegin="CONTAINER2014: "}</note>
|
||||
|
|
|
@ -55,7 +55,7 @@ partial class CreateNewImage
|
|||
/// The name of the output image that will be pushed to the registry.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string ImageName { get; set; }
|
||||
public string Repository { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The tag to associate with the new image.
|
||||
|
@ -140,7 +140,7 @@ partial class CreateNewImage
|
|||
BaseImageName = "";
|
||||
BaseImageTag = "";
|
||||
OutputRegistry = "";
|
||||
ImageName = "";
|
||||
Repository = "";
|
||||
ImageTags = Array.Empty<string>();
|
||||
PublishDirectory = "";
|
||||
WorkingDirectory = "";
|
||||
|
|
|
@ -41,7 +41,7 @@ public sealed partial class CreateNewImage : Microsoft.Build.Utilities.Task, ICa
|
|||
return !Log.HasLoggedErrors;
|
||||
}
|
||||
ImageReference sourceImageReference = new(SourceRegistry.Value, BaseImageName, BaseImageTag);
|
||||
var destinationImageReferences = ImageTags.Select(t => new ImageReference(DestinationRegistry.Value, ImageName, t));
|
||||
var destinationImageReferences = ImageTags.Select(t => new ImageReference(DestinationRegistry.Value, Repository, t));
|
||||
|
||||
ImageBuilder? imageBuilder;
|
||||
if (SourceRegistry.Value is { } registry)
|
||||
|
@ -64,7 +64,7 @@ public sealed partial class CreateNewImage : Microsoft.Build.Utilities.Task, ICa
|
|||
return !Log.HasLoggedErrors;
|
||||
}
|
||||
|
||||
SafeLog("Building image '{0}' with tags {1} on top of base image {2}", ImageName, String.Join(",", ImageTags), sourceImageReference);
|
||||
SafeLog("Building image '{0}' with tags {1} on top of base image {2}", Repository, String.Join(",", ImageTags), sourceImageReference);
|
||||
|
||||
Layer newLayer = Layer.FromDirectory(PublishDirectory, WorkingDirectory, imageBuilder.IsWindows);
|
||||
imageBuilder.AddLayer(newLayer);
|
||||
|
@ -167,7 +167,7 @@ public sealed partial class CreateNewImage : Microsoft.Build.Utilities.Task, ICa
|
|||
else
|
||||
{
|
||||
ContainerHelpers.ParsePortError parsedErrors = (ContainerHelpers.ParsePortError)errors!;
|
||||
|
||||
|
||||
if (parsedErrors.HasFlag(ContainerHelpers.ParsePortError.MissingPortNumber))
|
||||
{
|
||||
Log.LogErrorWithCodeFromResources(nameof(Strings.MissingPortNumber), port.ItemSpec);
|
||||
|
|
|
@ -86,9 +86,9 @@ public partial class CreateNewImage : ToolTask, ICancelableTask
|
|||
{
|
||||
throw new InvalidOperationException(Resource.FormatString(nameof(Strings.RequiredPropertyNotSetOrEmpty), nameof(BaseImageName)));
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(ImageName))
|
||||
if (string.IsNullOrWhiteSpace(Repository))
|
||||
{
|
||||
throw new InvalidOperationException(Resource.FormatString(nameof(Strings.RequiredPropertyNotSetOrEmpty), nameof(ImageName)));
|
||||
throw new InvalidOperationException(Resource.FormatString(nameof(Strings.RequiredPropertyNotSetOrEmpty), nameof(Repository)));
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(WorkingDirectory))
|
||||
{
|
||||
|
@ -110,7 +110,7 @@ public partial class CreateNewImage : ToolTask, ICancelableTask
|
|||
builder.AppendFileNameIfNotNull(PublishDirectory.TrimEnd(new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }));
|
||||
builder.AppendSwitchIfNotNull("--baseregistry ", BaseRegistry);
|
||||
builder.AppendSwitchIfNotNull("--baseimagename ", BaseImageName);
|
||||
builder.AppendSwitchIfNotNull("--imagename ", ImageName);
|
||||
builder.AppendSwitchIfNotNull("--repository ", Repository);
|
||||
builder.AppendSwitchIfNotNull("--workingdirectory ", WorkingDirectory);
|
||||
ITaskItem[] sanitizedEntryPoints = Entrypoint.Where(e => !string.IsNullOrWhiteSpace(e.ItemSpec)).ToArray();
|
||||
builder.AppendSwitchIfNotNull("--entrypoint ", sanitizedEntryPoints, delimiter: " ");
|
||||
|
|
|
@ -23,10 +23,10 @@ public sealed class ParseContainerProperties : Microsoft.Build.Utilities.Task
|
|||
public string ContainerRegistry { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The image name for the container to be created.
|
||||
/// The name of the container to be created.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string ContainerImageName { get; set; }
|
||||
public string ContainerRepository { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The tag for the container to be created.
|
||||
|
@ -55,7 +55,7 @@ public sealed class ParseContainerProperties : Microsoft.Build.Utilities.Task
|
|||
public string NewContainerRegistry { get; private set; }
|
||||
|
||||
[Output]
|
||||
public string NewContainerImageName { get; private set; }
|
||||
public string NewContainerRepository { get; private set; }
|
||||
|
||||
[Output]
|
||||
public string[] NewContainerTags { get; private set; }
|
||||
|
@ -67,7 +67,7 @@ public sealed class ParseContainerProperties : Microsoft.Build.Utilities.Task
|
|||
{
|
||||
FullyQualifiedBaseImageName = "";
|
||||
ContainerRegistry = "";
|
||||
ContainerImageName = "";
|
||||
ContainerRepository = "";
|
||||
ContainerImageTag = "";
|
||||
ContainerImageTags = Array.Empty<string>();
|
||||
ContainerEnvironmentVariables = Array.Empty<ITaskItem>();
|
||||
|
@ -75,7 +75,7 @@ public sealed class ParseContainerProperties : Microsoft.Build.Utilities.Task
|
|||
ParsedContainerImage = "";
|
||||
ParsedContainerTag = "";
|
||||
NewContainerRegistry = "";
|
||||
NewContainerImageName = "";
|
||||
NewContainerRepository = "";
|
||||
NewContainerTags = Array.Empty<string>();
|
||||
NewContainerEnvironmentVariables = Array.Empty<ITaskItem>();
|
||||
|
||||
|
@ -149,20 +149,20 @@ public sealed class ParseContainerProperties : Microsoft.Build.Utilities.Task
|
|||
|
||||
try
|
||||
{
|
||||
if (!ContainerHelpers.NormalizeImageName(ContainerImageName, out var normalizedImageName))
|
||||
if (!ContainerHelpers.NormalizeRepository(ContainerRepository, out var normalizedRepository))
|
||||
{
|
||||
Log.LogMessageFromResources(nameof(Strings.NormalizedContainerName), nameof(ContainerImageName), normalizedImageName);
|
||||
NewContainerImageName = normalizedImageName!; // known to be not null due to output of NormalizeImageName
|
||||
Log.LogMessageFromResources(nameof(Strings.NormalizedContainerName), nameof(ContainerRepository), normalizedRepository);
|
||||
NewContainerRepository = normalizedRepository!; // known to be not null due to output of NormalizeImageName
|
||||
}
|
||||
else
|
||||
{
|
||||
// name was valid already
|
||||
NewContainerImageName = ContainerImageName;
|
||||
NewContainerRepository = ContainerRepository;
|
||||
}
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
Log.LogErrorWithCodeFromResources(nameof(Strings.InvalidContainerImageName), nameof(ContainerImageName), ContainerImageName);
|
||||
Log.LogErrorWithCodeFromResources(nameof(Strings.InvalidContainerRepository), nameof(ContainerRepository), ContainerRepository);
|
||||
return !Log.HasLoggedErrors;
|
||||
}
|
||||
|
||||
|
@ -178,7 +178,7 @@ public sealed class ParseContainerProperties : Microsoft.Build.Utilities.Task
|
|||
Log.LogMessage(MessageImportance.Low, "Host: {0}", ParsedContainerRegistry);
|
||||
Log.LogMessage(MessageImportance.Low, "Image: {0}", ParsedContainerImage);
|
||||
Log.LogMessage(MessageImportance.Low, "Tag: {0}", ParsedContainerTag);
|
||||
Log.LogMessage(MessageImportance.Low, "Image Name: {0}", NewContainerImageName);
|
||||
Log.LogMessage(MessageImportance.Low, "Image Name: {0}", NewContainerRepository);
|
||||
Log.LogMessage(MessageImportance.Low, "Image Tags: {0}", String.Join(", ", NewContainerTags));
|
||||
}
|
||||
|
||||
|
|
|
@ -43,9 +43,9 @@ internal class ContainerizeCommand : RootCommand
|
|||
IsRequired = false
|
||||
};
|
||||
|
||||
internal Option<string> ImageNameOption { get; } = new Option<string>(
|
||||
name: "--imagename",
|
||||
description: "The name of the output image that will be pushed to the registry.")
|
||||
internal Option<string> RepositoryOption { get; } = new Option<string>(
|
||||
name: "--repository",
|
||||
description: "The name of the output container repository that will be pushed to the registry.")
|
||||
{
|
||||
IsRequired = true
|
||||
};
|
||||
|
@ -168,13 +168,13 @@ internal class ContainerizeCommand : RootCommand
|
|||
|
||||
|
||||
internal ContainerizeCommand() : base("Containerize an application without Docker.")
|
||||
{
|
||||
{
|
||||
this.AddArgument(PublishDirectoryArgument);
|
||||
this.AddOption(BaseRegistryOption);
|
||||
this.AddOption(BaseImageNameOption);
|
||||
this.AddOption(BaseImageTagOption);
|
||||
this.AddOption(OutputRegistryOption);
|
||||
this.AddOption(ImageNameOption);
|
||||
this.AddOption(RepositoryOption);
|
||||
this.AddOption(ImageTagsOption);
|
||||
this.AddOption(WorkingDirectoryOption);
|
||||
this.AddOption(EntrypointOption);
|
||||
|
@ -194,7 +194,7 @@ internal class ContainerizeCommand : RootCommand
|
|||
string _baseName = context.ParseResult.GetValue(BaseImageNameOption)!;
|
||||
string _baseTag = context.ParseResult.GetValue(BaseImageTagOption)!;
|
||||
string? _outputReg = context.ParseResult.GetValue(OutputRegistryOption);
|
||||
string _name = context.ParseResult.GetValue(ImageNameOption)!;
|
||||
string _name = context.ParseResult.GetValue(RepositoryOption)!;
|
||||
string[] _tags = context.ParseResult.GetValue(ImageTagsOption)!;
|
||||
string _workingDir = context.ParseResult.GetValue(WorkingDirectoryOption)!;
|
||||
string[] _entrypoint = context.ParseResult.GetValue(EntrypointOption)!;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<Nullable>enable</Nullable>
|
||||
<StrongNameKeyId>MicrosoftShared</StrongNameKeyId>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<ExcludeFromSourceBuild>true</ExcludeFromSourceBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -24,4 +25,9 @@
|
|||
</ItemGroup>
|
||||
<Copy SourceFiles="@(ContainerizeFiles)" DestinationFiles="@(ContainerizeFiles->'$(ArtifactsTmpDir)Container\containerize\%(RecursiveDir)%(Filename)%(Extension)')" />
|
||||
</Target>
|
||||
|
||||
<!-- Copy to *.csproj for using in sanity checks integration tests. -->
|
||||
<Target Name="CopyCsprojToTestExecutionDirectory" AfterTargets="Build">
|
||||
<Copy SourceFiles="$(MSBuildThisFileFullPath)" DestinationFiles="$(ArtifactsTmpDir)Container\ProjectFiles\$(MSBuildThisFileName).csproj" />
|
||||
</Target>
|
||||
</Project>
|
|
@ -69,6 +69,9 @@
|
|||
<ContainerImageTag Condition="'$(AutoGenerateImageTag)' == 'true'">$([System.DateTime]::UtcNow.ToString('yyyyMMddhhmmss'))</ContainerImageTag>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Compatibility: previous versions used ImageName, but the proper term is Repository. Keep using that if explicitly set. -->
|
||||
<Warning Condition="'$(ContainerImageName)' != ''" Code="CONTAINER003" Text="The property 'ContainerImageName' was set but is obsolete - please use 'ContainerRepository' instead." />
|
||||
|
||||
<!-- Container Defaults -->
|
||||
<PropertyGroup>
|
||||
<!-- An empty ContainerRegistry implies pushing to the local registry, putting this here for documentation purposes -->
|
||||
|
@ -77,8 +80,10 @@
|
|||
<!-- Set which local container registry to use. We only explicitly support Docker (or things that mimic Docker APIs and binary names) at the moment. -->
|
||||
<LocalRegistry Condition="'$(LocalRegistry)' == ''">Docker</LocalRegistry>
|
||||
|
||||
<!-- Note: spaces will be replaced with '-' in ContainerImageName and ContainerImageTag -->
|
||||
<ContainerImageName Condition="'$(ContainerImageName)' == ''">$(AssemblyName)</ContainerImageName>
|
||||
<!-- Compatibility: previous versions used ImageName, but the proper term is Repository. Keep using that if explicitly set. -->
|
||||
<ContainerRepository Condition="'$(ContainerImageName)' != ''">$(ContainerImageName)</ContainerRepository>
|
||||
<!-- Note: spaces will be replaced with '-' in ContainerRepository and ContainerImageTag -->
|
||||
<ContainerRepository Condition="'$(ContainerRepository)' == ''">$(AssemblyName)</ContainerRepository>
|
||||
|
||||
<!-- Only default a tag name if no tag names at all are provided -->
|
||||
<ContainerImageTag Condition="'$(ContainerImageTag)' == '' and '$(ContainerImageTags)' == ''">$(Version)</ContainerImageTag>
|
||||
|
@ -113,7 +118,7 @@
|
|||
|
||||
<ParseContainerProperties FullyQualifiedBaseImageName="$(ContainerBaseImage)"
|
||||
ContainerRegistry="$(ContainerRegistry)"
|
||||
ContainerImageName="$(ContainerImageName)"
|
||||
ContainerRepository="$(ContainerRepository)"
|
||||
ContainerImageTag="$(ContainerImageTag)"
|
||||
ContainerImageTags="$(ContainerImageTags)"
|
||||
ContainerEnvironmentVariables="@(ContainerEnvironmentVariable)">
|
||||
|
@ -122,7 +127,7 @@
|
|||
<Output TaskParameter="ParsedContainerImage" PropertyName="ContainerBaseName" />
|
||||
<Output TaskParameter="ParsedContainerTag" PropertyName="ContainerBaseTag" />
|
||||
<Output TaskParameter="NewContainerRegistry" PropertyName="ContainerRegistry" />
|
||||
<Output TaskParameter="NewContainerImageName" PropertyName="ContainerImageName" />
|
||||
<Output TaskParameter="NewContainerRepository" PropertyName="ContainerRepository" />
|
||||
<Output TaskParameter="NewContainerTags" ItemName="ContainerImageTags" />
|
||||
<Output TaskParameter="NewContainerEnvironmentVariables" ItemName="ContainerEnvironmentVariables" />
|
||||
</ParseContainerProperties>
|
||||
|
@ -201,7 +206,7 @@
|
|||
BaseImageTag="$(ContainerBaseTag)"
|
||||
LocalRegistry="$(LocalRegistry)"
|
||||
OutputRegistry="$(ContainerRegistry)"
|
||||
ImageName="$(ContainerImageName)"
|
||||
Repository="$(ContainerRepository)"
|
||||
ImageTags="@(ContainerImageTags)"
|
||||
PublishDirectory="$(PublishDir)"
|
||||
WorkingDirectory="$(ContainerWorkingDirectory)"
|
||||
|
|
|
@ -28,12 +28,15 @@
|
|||
SetTargetFramework="TargetFramework=$(TargetFramework)"
|
||||
OutputItemType="ContainerLibraryOutput"/>
|
||||
|
||||
<ProjectReference Include="../../Cli/Microsoft.DotNet.Cli.Utils/Microsoft.DotNet.Cli.Utils.csproj"
|
||||
SetTargetFramework="TargetFramework=$(TargetFramework)"
|
||||
OutputItemType="DotNetCliUtilsLibraryOutput"/>
|
||||
|
||||
<ProjectReference Include="../Microsoft.NET.Build.Containers/Microsoft.NET.Build.Containers.csproj"
|
||||
SetTargetFramework="TargetFramework=$(VSCompatTargetFramework)"
|
||||
OutputItemType="ContainerLibraryOutputNet472" Condition="'$(DotNetBuildFromSource)' != 'true'" />
|
||||
|
||||
<ProjectReference Include="../containerize/containerize.csproj" PrivateAssets="all" IncludeAssets="runtime" ReferenceOutputAssembly="true" />
|
||||
<PackageReference Include="System.CommandLine" PrivateAssets="all" IncludeAssets="runtime" Version="$(SystemCommandLineVersion)"/>
|
||||
<ProjectReference Include="../containerize/containerize.csproj" PrivateAssets="all" IncludeAssets="runtime" ReferenceOutputAssembly="true" Condition="'$(DotNetBuildFromSource)' != 'true'" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PreparePackageReleaseNotesFromFile" BeforeTargets="GenerateNuspec">
|
||||
|
@ -48,18 +51,12 @@
|
|||
<Output TaskParameter="TargetOutputs" ItemName="_AllNet472ContainerTaskDependencies" />
|
||||
</MSBuild>
|
||||
<ItemGroup Condition="'$(DotNetBuildFromSource)' != 'true'">
|
||||
<NecessaryNet472ContainerTaskDependencies
|
||||
Include="@(_AllNet472ContainerTaskDependencies)"
|
||||
Condition="(
|
||||
$([MSBuild]::ValueOrDefault('%(_AllNet472ContainerTaskDependencies.NuGetPackageId)', '').Contains('NuGet')) or
|
||||
$([MSBuild]::ValueOrDefault('%(_AllNet472ContainerTaskDependencies.NuGetPackageId)', '').Contains('Newtonsoft'))
|
||||
) and
|
||||
%(_AllNet472ContainerTaskDependencies.NuGetIsFrameworkReference) != true" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<!-- root folder -->
|
||||
<Content Include="README.md" Pack="true" PackagePath="" />
|
||||
|
||||
<NecessaryNet472ContainerTaskDependencies Include="@(_AllNet472ContainerTaskDependencies)" Condition="(
|
||||
$([MSBuild]::ValueOrDefault('%(_AllNet472ContainerTaskDependencies.NuGetPackageId)', '').Contains('NuGet')) or
|
||||
$([MSBuild]::ValueOrDefault('%(_AllNet472ContainerTaskDependencies.NuGetPackageId)', '').Contains('Newtonsoft'))
|
||||
) and
|
||||
%(_AllNet472ContainerTaskDependencies.NuGetIsFrameworkReference) != true" />
|
||||
|
||||
<!-- containerize folder -->
|
||||
<Content Include="$(OutDir)containerize.dll" Pack="true" PackagePath="containerize/" />
|
||||
<Content Include="$(OutDir)containerize.runtimeconfig.json" Pack="true" PackagePath="containerize/" />
|
||||
|
@ -70,25 +67,37 @@
|
|||
<Content Include="$(OutDir)Valleysoft.DockerCredsProvider.dll" Pack="true" PackagePath="containerize/" />
|
||||
<Content Include="@(ContainerLibraryOutput)" Pack="true" PackagePath="containerize/" />
|
||||
|
||||
<!-- net472 tasks -->
|
||||
<!-- dependencies -->
|
||||
<Content Include="@(NecessaryNet472ContainerTaskDependencies)" Pack="true" PackagePath="tasks/$(VSCompatTargetFramework)/" />
|
||||
<!-- actual DLL -->
|
||||
<Content Include="@(ContainerLibraryOutputNet472)" Pack="true" PackagePath="tasks/$(VSCompatTargetFramework)/" />
|
||||
</ItemGroup>
|
||||
<MSBuild Projects="../Microsoft.NET.Build.Containers/Microsoft.NET.Build.Containers.csproj" Properties="TargetFramework=$(TargetFramework)" Targets="ResolveAssemblyReferences">
|
||||
<Output TaskParameter="TargetOutputs" ItemName="_AllNetContainerTaskDependencies" />
|
||||
</MSBuild>
|
||||
<ItemGroup>
|
||||
<NecessaryNetContainerTaskDependencies Include="@(_AllNetContainerTaskDependencies)" Condition="(
|
||||
$([MSBuild]::ValueOrDefault('%(_AllNetContainerTaskDependencies.NuGetPackageId)', '').Contains('NuGet')) or
|
||||
$([MSBuild]::ValueOrDefault('%(_AllNetContainerTaskDependencies.NuGetPackageId)', '').Contains('Newtonsoft')) or
|
||||
$([MSBuild]::ValueOrDefault('%(_AllNetContainerTaskDependencies.NuGetPackageId)', '').Contains('Valleysoft'))
|
||||
) and
|
||||
%(_AllNetContainerTaskDependencies.NuGetIsFrameworkReference) != true" />
|
||||
|
||||
<!-- root folder -->
|
||||
<Content Include="README.md" Pack="true" PackagePath="" />
|
||||
|
||||
<!-- tasks folder -->
|
||||
<!-- net7.0 tasks -->
|
||||
<!-- dependencies -->
|
||||
<Content Include="$(OutDir)Valleysoft.DockerCredsProvider.dll" Pack="true" PackagePath="tasks/$(TargetFramework)" />
|
||||
<Content Include="$(OutDir)NuGet.*.dll" Pack="true" PackagePath="tasks/$(TargetFramework)" />
|
||||
<Content Include="$(OutDir)Newtonsoft.Json.dll" Pack="true" PackagePath="tasks/$(TargetFramework)" />
|
||||
<Content Include="$(OutDir)Microsoft.DotNet.Cli.Utils.dll" Pack="true" PackagePath="tasks/$(TargetFramework)" />
|
||||
<Content Include="@(NecessaryNetContainerTaskDependencies)" Pack="true" PackagePath="tasks/$(TargetFramework)/" />
|
||||
<Content Include="@(DotNetCliUtilsLibraryOutput)" Pack="true" PackagePath="tasks/$(TargetFramework)/" />
|
||||
|
||||
<!-- runtime deps json -->
|
||||
<Content Include="$(ArtifactsDir)bin/Microsoft.NET.Build.Containers/$(Configuration)/$(TargetFramework)/Microsoft.NET.Build.Containers.deps.json" Pack="true" PackagePath="tasks/$(TargetFramework)" />
|
||||
<!-- actual DLL -->
|
||||
<Content Include="@(ContainerLibraryOutput)" Pack="true" PackagePath="tasks/$(TargetFramework)/" />
|
||||
|
||||
<!-- net472 tasks -->
|
||||
<!-- dependencies -->
|
||||
<Content Include="@(NecessaryNet472ContainerTaskDependencies)" Pack="true" PackagePath="tasks/$(VSCompatTargetFramework)/" Condition="'$(DotNetBuildFromSource)' != 'true'" />
|
||||
<!-- runtime deps json isn't valid for netfx -->
|
||||
<!-- actual DLL -->
|
||||
<Content Include="@(ContainerLibraryOutputNet472)" Pack="true" PackagePath="tasks/$(VSCompatTargetFramework)/" Condition="'$(DotNetBuildFromSource)' != 'true'" />
|
||||
|
||||
<!-- build folder -->
|
||||
<Content Include="build/**" Pack="true" PackagePath="build/" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -209,7 +209,8 @@
|
|||
<MSBuild
|
||||
Targets="Publish"
|
||||
Projects="$(RepoRoot)/src/Containers/containerize/containerize.csproj"
|
||||
Properties="Configuration=$(Configuration);PublishDir=$(OutputPath)/Containers/containerize" />
|
||||
Properties="Configuration=$(Configuration);PublishDir=$(OutputPath)/Containers/containerize"
|
||||
Condition="'$(DotNetBuildFromSource)' != 'true'" />
|
||||
</Target>
|
||||
|
||||
<Target Name="GenerateCliRuntimeConfigurationFiles"
|
||||
|
|
|
@ -14,6 +14,8 @@ namespace Microsoft.NET.Sdk.WorkloadManifestReader
|
|||
{
|
||||
public class SdkDirectoryWorkloadManifestProvider : IWorkloadManifestProvider
|
||||
{
|
||||
private const string WorkloadSetsFolderName = "workloadsets";
|
||||
|
||||
private readonly string _sdkRootPath;
|
||||
private readonly SdkFeatureBand _sdkVersionBand;
|
||||
private readonly string[] _manifestRoots;
|
||||
|
@ -21,15 +23,15 @@ namespace Microsoft.NET.Sdk.WorkloadManifestReader
|
|||
"microsoft.net.workload.maccatalyst", "microsoft.net.workload.macos", "microsoft.net.workload.tvos", "microsoft.net.workload.mono.toolchain" };
|
||||
private readonly Dictionary<string, int>? _knownManifestIdsAndOrder;
|
||||
|
||||
private readonly Dictionary<string, ManifestSpecifier> _requestedManifestVersions;
|
||||
private readonly WorkloadSet? _workloadSet;
|
||||
|
||||
public SdkDirectoryWorkloadManifestProvider(string sdkRootPath, string sdkVersion, string? userProfileDir, IEnumerable<ManifestSpecifier>? requestedManifestVersions = null)
|
||||
: this(sdkRootPath, sdkVersion, Environment.GetEnvironmentVariable, userProfileDir, requestedManifestVersions)
|
||||
public SdkDirectoryWorkloadManifestProvider(string sdkRootPath, string sdkVersion, string? userProfileDir, string? requestedWorkloadSet = null)
|
||||
: this(sdkRootPath, sdkVersion, Environment.GetEnvironmentVariable, userProfileDir, requestedWorkloadSet)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
internal SdkDirectoryWorkloadManifestProvider(string sdkRootPath, string sdkVersion, Func<string, string?> getEnvironmentVariable, string? userProfileDir, IEnumerable<ManifestSpecifier>? requestedManifestVersions = null)
|
||||
internal SdkDirectoryWorkloadManifestProvider(string sdkRootPath, string sdkVersion, Func<string, string?> getEnvironmentVariable, string? userProfileDir, string? requestedWorkloadSet = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(sdkVersion))
|
||||
{
|
||||
|
@ -87,15 +89,19 @@ namespace Microsoft.NET.Sdk.WorkloadManifestReader
|
|||
|
||||
_manifestRoots = _manifestRoots ?? Array.Empty<string>();
|
||||
|
||||
_requestedManifestVersions = new Dictionary<string, ManifestSpecifier>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
if (requestedManifestVersions != null)
|
||||
var availableWorkloadSets = GetAvailableWorkloadSets();
|
||||
if (requestedWorkloadSet != null)
|
||||
{
|
||||
foreach (var manifestVersion in requestedManifestVersions)
|
||||
if (!availableWorkloadSets.TryGetValue(requestedWorkloadSet, out _workloadSet))
|
||||
{
|
||||
_requestedManifestVersions[manifestVersion.Id.ToString()] = manifestVersion;
|
||||
throw new FileNotFoundException(string.Format(Strings.SpecifiedWorkloadSetNotFound, requestedWorkloadSet));
|
||||
}
|
||||
}
|
||||
else if (availableWorkloadSets.Any())
|
||||
{
|
||||
var maxWorkloadSetVersion = availableWorkloadSets.Keys.Select(k => new ReleaseVersion(k)).Max()!;
|
||||
_workloadSet = availableWorkloadSets[maxWorkloadSetVersion.ToString()];
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<ReadableWorkloadManifest> GetManifests()
|
||||
|
@ -117,7 +123,7 @@ namespace Microsoft.NET.Sdk.WorkloadManifestReader
|
|||
public IEnumerable<string> GetManifestDirectories()
|
||||
{
|
||||
// Scan manifest directories
|
||||
var manifestIdsToDirectories = new Dictionary<string, string>();
|
||||
var manifestIdsToDirectories = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
void ProbeDirectory(string manifestDirectory)
|
||||
{
|
||||
|
@ -162,10 +168,13 @@ namespace Microsoft.NET.Sdk.WorkloadManifestReader
|
|||
}
|
||||
}
|
||||
|
||||
// Load manifests that were explicitly specified
|
||||
foreach (var kvp in _requestedManifestVersions)
|
||||
// Load manifests from workload set, if any
|
||||
if (_workloadSet != null)
|
||||
{
|
||||
manifestIdsToDirectories.Add(kvp.Key, GetManifestDirectoryFromSpecifier(kvp.Value));
|
||||
foreach (var kvp in _workloadSet.ManifestVersions)
|
||||
{
|
||||
manifestIdsToDirectories[kvp.Key.ToString()] = GetManifestDirectoryFromSpecifier(new ManifestSpecifier(kvp.Key, kvp.Value.Version, kvp.Value.FeatureBand));
|
||||
}
|
||||
}
|
||||
|
||||
if (_knownManifestIdsAndOrder != null && _knownManifestIdsAndOrder.Keys.Any(id => !manifestIdsToDirectories.ContainsKey(id)))
|
||||
|
@ -205,7 +214,8 @@ namespace Microsoft.NET.Sdk.WorkloadManifestReader
|
|||
private (string? id, string? manifestDirectory) ResolveManifestDirectory(string manifestDirectory)
|
||||
{
|
||||
string manifestId = Path.GetFileName(manifestDirectory);
|
||||
if (_outdatedManifestIds.Contains(manifestId))
|
||||
if (_outdatedManifestIds.Contains(manifestId) ||
|
||||
manifestId.Equals(WorkloadSetsFolderName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return (null, null);
|
||||
}
|
||||
|
@ -285,10 +295,48 @@ namespace Microsoft.NET.Sdk.WorkloadManifestReader
|
|||
throw new FileNotFoundException(string.Format(Strings.SpecifiedManifestNotFound, manifestSpecifier.ToString()));
|
||||
}
|
||||
|
||||
private bool IsManifestIdOutdated(string workloadManifestDir)
|
||||
/// <summary>
|
||||
/// Returns installed workload sets that are available for this SDK (ie are in the same feature band)
|
||||
/// </summary>
|
||||
private Dictionary<string, WorkloadSet> GetAvailableWorkloadSets()
|
||||
{
|
||||
var manifestId = Path.GetFileName(workloadManifestDir);
|
||||
return _outdatedManifestIds.Contains(manifestId);
|
||||
Dictionary<string, WorkloadSet> availableWorkloadSets = new Dictionary<string, WorkloadSet>();
|
||||
|
||||
foreach (var manifestRoot in _manifestRoots.Reverse())
|
||||
{
|
||||
// Workload sets must match the SDK feature band, we don't support any fallback to a previous band
|
||||
var workloadSetsRoot = Path.Combine(manifestRoot, _sdkVersionBand.ToString(), WorkloadSetsFolderName);
|
||||
if (Directory.Exists(workloadSetsRoot))
|
||||
{
|
||||
foreach (var workloadSetDirectory in Directory.GetDirectories(workloadSetsRoot))
|
||||
{
|
||||
WorkloadSet? workloadSet = null;
|
||||
foreach (var jsonFile in Directory.GetFiles(workloadSetDirectory, "*.workloadset.json"))
|
||||
{
|
||||
var newWorkloadSet = WorkloadSet.FromJson(File.ReadAllText(jsonFile), _sdkVersionBand);
|
||||
if (workloadSet == null)
|
||||
{
|
||||
workloadSet = newWorkloadSet;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If there are multiple workloadset.json files, merge them
|
||||
foreach (var kvp in newWorkloadSet.ManifestVersions)
|
||||
{
|
||||
workloadSet.ManifestVersions.Add(kvp.Key, kvp.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (workloadSet != null)
|
||||
{
|
||||
workloadSet.Version = Path.GetFileName(workloadSetDirectory);
|
||||
availableWorkloadSets[workloadSet.Version] = workloadSet;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return availableWorkloadSets;
|
||||
}
|
||||
|
||||
public string GetSdkFeatureBand()
|
||||
|
|
|
@ -192,4 +192,10 @@
|
|||
<data name="SpecifiedManifestNotFound" xml:space="preserve">
|
||||
<value>Specified workload manifest was not found: {0}</value>
|
||||
</data>
|
||||
<data name="SpecifiedWorkloadSetNotFound" xml:space="preserve">
|
||||
<value>Specified workload set was not found: {0}</value>
|
||||
</data>
|
||||
<data name="InvalidVersionForWorkload" xml:space="preserve">
|
||||
<value>Error parsing version '{1}' for workload manifest ID '{0}'</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.DotNet.MSBuildSdkResolver;
|
||||
using Strings = Microsoft.NET.Sdk.Localization.Strings;
|
||||
|
||||
|
||||
#if USE_SYSTEM_TEXT_JSON
|
||||
using System.Text.Json;
|
||||
#else
|
||||
using Newtonsoft.Json;
|
||||
#endif
|
||||
|
||||
|
||||
namespace Microsoft.NET.Sdk.WorkloadManifestReader
|
||||
{
|
||||
public class WorkloadSet
|
||||
{
|
||||
public Dictionary<ManifestId, (ManifestVersion Version, SdkFeatureBand FeatureBand)> ManifestVersions = new Dictionary<ManifestId, (ManifestVersion version, SdkFeatureBand featureBand)>();
|
||||
|
||||
// TODO: Generate version from hash of manifest versions if not otherwise set
|
||||
public string? Version { get; set; }
|
||||
|
||||
public static WorkloadSet FromManifests(IEnumerable<WorkloadManifestInfo> manifests)
|
||||
{
|
||||
return new WorkloadSet()
|
||||
{
|
||||
ManifestVersions = manifests.ToDictionary(m => new ManifestId(m.Id), m => (new ManifestVersion(m.Version), new SdkFeatureBand(m.ManifestFeatureBand)))
|
||||
};
|
||||
}
|
||||
|
||||
public static WorkloadSet FromDictionaryForJson(IDictionary<string, string> dictionary, SdkFeatureBand defaultFeatureBand)
|
||||
{
|
||||
var manifestVersions = dictionary
|
||||
.Select(manifest =>
|
||||
{
|
||||
ManifestVersion manifestVersion;
|
||||
SdkFeatureBand manifestFeatureBand;
|
||||
var parts = manifest.Value.Split('/');
|
||||
|
||||
string manifestVersionString = parts[0];
|
||||
if (!FXVersion.TryParse(manifestVersionString, out FXVersion version))
|
||||
{
|
||||
throw new FormatException(String.Format(Strings.InvalidVersionForWorkload, manifest.Key, manifestVersionString));
|
||||
}
|
||||
|
||||
manifestVersion = new ManifestVersion(parts[0]);
|
||||
if (parts.Length == 1)
|
||||
{
|
||||
manifestFeatureBand = defaultFeatureBand;
|
||||
}
|
||||
else
|
||||
{
|
||||
manifestFeatureBand = new SdkFeatureBand(parts[1]);
|
||||
}
|
||||
return (id: new ManifestId(manifest.Key), manifestVersion, manifestFeatureBand);
|
||||
}).ToDictionary(t => t.id, t => (t.manifestVersion, t.manifestFeatureBand));
|
||||
|
||||
return new WorkloadSet()
|
||||
{
|
||||
ManifestVersions = manifestVersions
|
||||
};
|
||||
}
|
||||
|
||||
public static WorkloadSet FromJson(string json, SdkFeatureBand defaultFeatureBand)
|
||||
{
|
||||
#if USE_SYSTEM_TEXT_JSON
|
||||
return FromDictionaryForJson(JsonSerializer.Deserialize<IDictionary<string, string>>(json)!, defaultFeatureBand);
|
||||
#else
|
||||
return FromDictionaryForJson(JsonConvert.DeserializeObject<IDictionary<string, string>>(json)!, defaultFeatureBand);
|
||||
#endif
|
||||
}
|
||||
|
||||
public Dictionary<string, string> ToDictionaryForJson()
|
||||
{
|
||||
var dictionary = ManifestVersions.ToDictionary(kvp => kvp.Key.ToString(), kvp => kvp.Value.Version + "/" + kvp.Value.FeatureBand, StringComparer.OrdinalIgnoreCase);
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
public string ToJson()
|
||||
{
|
||||
#if USE_SYSTEM_TEXT_JSON
|
||||
var json = JsonSerializer.Serialize(ToDictionaryForJson(), new JsonSerializerOptions() { WriteIndented = true });
|
||||
#else
|
||||
var json = JsonConvert.SerializeObject(ToDictionaryForJson(), Formatting.Indented);
|
||||
#endif
|
||||
return json;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -62,6 +62,11 @@
|
|||
<target state="translated">Neplatná verze: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidVersionForWorkload">
|
||||
<source>Error parsing version '{1}' for workload manifest ID '{0}'</source>
|
||||
<target state="new">Error parsing version '{1}' for workload manifest ID '{0}'</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ManifestDependencyMissing">
|
||||
<source>Did not find workload manifest dependency '{0}' required by manifest '{1}' [{2}]</source>
|
||||
<target state="translated">Nebyla nalezena závislost manifestu úlohy {0} požadovaná manifestem {1} [{2}].</target>
|
||||
|
@ -102,6 +107,11 @@
|
|||
<target state="translated">Zadaný manifest úlohy se nenašel: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="SpecifiedWorkloadSetNotFound">
|
||||
<source>Specified workload set was not found: {0}</source>
|
||||
<target state="new">Specified workload set was not found: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="UnexpectedTokenAtOffset">
|
||||
<source>Unexpected token '{0}' at offset {1}</source>
|
||||
<target state="translated">Neočekávaný token {0} u posunu {1}</target>
|
||||
|
|
|
@ -62,6 +62,11 @@
|
|||
<target state="translated">Ungültige Version: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidVersionForWorkload">
|
||||
<source>Error parsing version '{1}' for workload manifest ID '{0}'</source>
|
||||
<target state="new">Error parsing version '{1}' for workload manifest ID '{0}'</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ManifestDependencyMissing">
|
||||
<source>Did not find workload manifest dependency '{0}' required by manifest '{1}' [{2}]</source>
|
||||
<target state="translated">Die Workloadmanifestabhängigkeit „{0}“, die vom Manifest „{1}“ [{2}] benötigt wird, wurde nicht gefunden.</target>
|
||||
|
@ -102,6 +107,11 @@
|
|||
<target state="translated">Das angegebene Workloadmanifest wurde nicht gefunden: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="SpecifiedWorkloadSetNotFound">
|
||||
<source>Specified workload set was not found: {0}</source>
|
||||
<target state="new">Specified workload set was not found: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="UnexpectedTokenAtOffset">
|
||||
<source>Unexpected token '{0}' at offset {1}</source>
|
||||
<target state="translated">Unerwartetes Token "{0}" bei Offset {1}.</target>
|
||||
|
|
|
@ -62,6 +62,11 @@
|
|||
<target state="translated">Versión no válida: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidVersionForWorkload">
|
||||
<source>Error parsing version '{1}' for workload manifest ID '{0}'</source>
|
||||
<target state="new">Error parsing version '{1}' for workload manifest ID '{0}'</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ManifestDependencyMissing">
|
||||
<source>Did not find workload manifest dependency '{0}' required by manifest '{1}' [{2}]</source>
|
||||
<target state="translated">No se ha encontrado la dependencia del manifiesto de carga de trabajo '{0}' requerida por el manifiesto '{1}' [{2}]</target>
|
||||
|
@ -102,6 +107,11 @@
|
|||
<target state="translated">No se encontró el manifiesto de carga de trabajo especificado: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="SpecifiedWorkloadSetNotFound">
|
||||
<source>Specified workload set was not found: {0}</source>
|
||||
<target state="new">Specified workload set was not found: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="UnexpectedTokenAtOffset">
|
||||
<source>Unexpected token '{0}' at offset {1}</source>
|
||||
<target state="translated">Token "{0}" inesperado en el desplazamiento {1}</target>
|
||||
|
|
|
@ -62,6 +62,11 @@
|
|||
<target state="translated">Version non valide : {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidVersionForWorkload">
|
||||
<source>Error parsing version '{1}' for workload manifest ID '{0}'</source>
|
||||
<target state="new">Error parsing version '{1}' for workload manifest ID '{0}'</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ManifestDependencyMissing">
|
||||
<source>Did not find workload manifest dependency '{0}' required by manifest '{1}' [{2}]</source>
|
||||
<target state="translated">La dépendance de manifeste de charge de travail « {0} » requise par le manifeste « {1} » [{2}] est introuvable</target>
|
||||
|
@ -102,6 +107,11 @@
|
|||
<target state="translated">Le manifeste de charge de travail spécifié est introuvable : {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="SpecifiedWorkloadSetNotFound">
|
||||
<source>Specified workload set was not found: {0}</source>
|
||||
<target state="new">Specified workload set was not found: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="UnexpectedTokenAtOffset">
|
||||
<source>Unexpected token '{0}' at offset {1}</source>
|
||||
<target state="translated">Jeton '{0}' inattendu à l'offset {1}</target>
|
||||
|
|
|
@ -62,6 +62,11 @@
|
|||
<target state="translated">Versione non valida: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidVersionForWorkload">
|
||||
<source>Error parsing version '{1}' for workload manifest ID '{0}'</source>
|
||||
<target state="new">Error parsing version '{1}' for workload manifest ID '{0}'</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ManifestDependencyMissing">
|
||||
<source>Did not find workload manifest dependency '{0}' required by manifest '{1}' [{2}]</source>
|
||||
<target state="translated">La dipendenza del manifesto del carico di lavoro '{0}' richiesta dal manifesto '{1}' [{2}] non è stata trovata</target>
|
||||
|
@ -102,6 +107,11 @@
|
|||
<target state="translated">Il manifesto del carico di lavoro specificato non è stato trovato: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="SpecifiedWorkloadSetNotFound">
|
||||
<source>Specified workload set was not found: {0}</source>
|
||||
<target state="new">Specified workload set was not found: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="UnexpectedTokenAtOffset">
|
||||
<source>Unexpected token '{0}' at offset {1}</source>
|
||||
<target state="translated">Token '{0}' imprevisto alla posizione di offset {1}</target>
|
||||
|
|
|
@ -62,6 +62,11 @@
|
|||
<target state="translated">無効なバージョン: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidVersionForWorkload">
|
||||
<source>Error parsing version '{1}' for workload manifest ID '{0}'</source>
|
||||
<target state="new">Error parsing version '{1}' for workload manifest ID '{0}'</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ManifestDependencyMissing">
|
||||
<source>Did not find workload manifest dependency '{0}' required by manifest '{1}' [{2}]</source>
|
||||
<target state="translated">マニフェスト '{1}' [{2}] で必要なワークロード マニフェストの依存関係 '{0}' が見つかりません</target>
|
||||
|
@ -102,6 +107,11 @@
|
|||
<target state="translated">指定されたワークロード マニフェストが見つかりませんでした: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="SpecifiedWorkloadSetNotFound">
|
||||
<source>Specified workload set was not found: {0}</source>
|
||||
<target state="new">Specified workload set was not found: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="UnexpectedTokenAtOffset">
|
||||
<source>Unexpected token '{0}' at offset {1}</source>
|
||||
<target state="translated">オフセット {1} に予期しないトークン '{0}' があります</target>
|
||||
|
|
|
@ -62,6 +62,11 @@
|
|||
<target state="translated">잘못된 버전: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidVersionForWorkload">
|
||||
<source>Error parsing version '{1}' for workload manifest ID '{0}'</source>
|
||||
<target state="new">Error parsing version '{1}' for workload manifest ID '{0}'</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ManifestDependencyMissing">
|
||||
<source>Did not find workload manifest dependency '{0}' required by manifest '{1}' [{2}]</source>
|
||||
<target state="translated">매니페스트 '{1}' [{2}]에 필요한 워크로드 매니페스트 종속성 '{0}'을(를) 찾지 못했습니다</target>
|
||||
|
@ -102,6 +107,11 @@
|
|||
<target state="translated">지정한 워크로드 매니페스트를 찾을 수 없습니다. {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="SpecifiedWorkloadSetNotFound">
|
||||
<source>Specified workload set was not found: {0}</source>
|
||||
<target state="new">Specified workload set was not found: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="UnexpectedTokenAtOffset">
|
||||
<source>Unexpected token '{0}' at offset {1}</source>
|
||||
<target state="translated">오프셋 {1}에 예기치 않은 토큰 '{0}'이(가) 있습니다.</target>
|
||||
|
|
|
@ -62,6 +62,11 @@
|
|||
<target state="translated">Nieprawidłowa wersja: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidVersionForWorkload">
|
||||
<source>Error parsing version '{1}' for workload manifest ID '{0}'</source>
|
||||
<target state="new">Error parsing version '{1}' for workload manifest ID '{0}'</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ManifestDependencyMissing">
|
||||
<source>Did not find workload manifest dependency '{0}' required by manifest '{1}' [{2}]</source>
|
||||
<target state="translated">Nie znaleziono zależności manifestu obciążenia „{0}” wymaganej przez manifest „{1}” [{2}]</target>
|
||||
|
@ -102,6 +107,11 @@
|
|||
<target state="translated">Nie znaleziono określonego manifestu obciążenia: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="SpecifiedWorkloadSetNotFound">
|
||||
<source>Specified workload set was not found: {0}</source>
|
||||
<target state="new">Specified workload set was not found: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="UnexpectedTokenAtOffset">
|
||||
<source>Unexpected token '{0}' at offset {1}</source>
|
||||
<target state="translated">Nieoczekiwany token „{0}” pod przesunięciem {1}</target>
|
||||
|
|
|
@ -62,6 +62,11 @@
|
|||
<target state="translated">Versão inválida: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidVersionForWorkload">
|
||||
<source>Error parsing version '{1}' for workload manifest ID '{0}'</source>
|
||||
<target state="new">Error parsing version '{1}' for workload manifest ID '{0}'</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ManifestDependencyMissing">
|
||||
<source>Did not find workload manifest dependency '{0}' required by manifest '{1}' [{2}]</source>
|
||||
<target state="translated">Não foi possível encontrar a dependência do manifesto de carga de trabalho '{0}' exigida pelo manifesto '{1}' [{2}]</target>
|
||||
|
@ -102,6 +107,11 @@
|
|||
<target state="translated">O manifesto de carga de trabalho especificado não foi encontrado: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="SpecifiedWorkloadSetNotFound">
|
||||
<source>Specified workload set was not found: {0}</source>
|
||||
<target state="new">Specified workload set was not found: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="UnexpectedTokenAtOffset">
|
||||
<source>Unexpected token '{0}' at offset {1}</source>
|
||||
<target state="translated">Token inesperado '{0}' no deslocamento {1}</target>
|
||||
|
|
|
@ -62,6 +62,11 @@
|
|||
<target state="translated">Недопустимая версия: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidVersionForWorkload">
|
||||
<source>Error parsing version '{1}' for workload manifest ID '{0}'</source>
|
||||
<target state="new">Error parsing version '{1}' for workload manifest ID '{0}'</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ManifestDependencyMissing">
|
||||
<source>Did not find workload manifest dependency '{0}' required by manifest '{1}' [{2}]</source>
|
||||
<target state="translated">Не найдена зависимость манифеста рабочей нагрузки "{0}", необходимая для манифеста "{1}" [{2}]</target>
|
||||
|
@ -102,6 +107,11 @@
|
|||
<target state="translated">Указанный манифест рабочей нагрузки не найден: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="SpecifiedWorkloadSetNotFound">
|
||||
<source>Specified workload set was not found: {0}</source>
|
||||
<target state="new">Specified workload set was not found: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="UnexpectedTokenAtOffset">
|
||||
<source>Unexpected token '{0}' at offset {1}</source>
|
||||
<target state="translated">Непредвиденный токен "{0}" в смещении {1}</target>
|
||||
|
|
|
@ -62,6 +62,11 @@
|
|||
<target state="translated">Geçersiz sürüm: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidVersionForWorkload">
|
||||
<source>Error parsing version '{1}' for workload manifest ID '{0}'</source>
|
||||
<target state="new">Error parsing version '{1}' for workload manifest ID '{0}'</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ManifestDependencyMissing">
|
||||
<source>Did not find workload manifest dependency '{0}' required by manifest '{1}' [{2}]</source>
|
||||
<target state="translated">{1}' [{2}] bildirimi için gereken '{0}' iş yükü bildirimi bağımlılığı bulunamadı</target>
|
||||
|
@ -102,6 +107,11 @@
|
|||
<target state="translated">Belirtilen iş yükü bildirimi bulunamadı: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="SpecifiedWorkloadSetNotFound">
|
||||
<source>Specified workload set was not found: {0}</source>
|
||||
<target state="new">Specified workload set was not found: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="UnexpectedTokenAtOffset">
|
||||
<source>Unexpected token '{0}' at offset {1}</source>
|
||||
<target state="translated">{1} uzaklığında beklenmeyen '{0}' belirteci</target>
|
||||
|
|
|
@ -62,6 +62,11 @@
|
|||
<target state="translated">版本 {0} 无效</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidVersionForWorkload">
|
||||
<source>Error parsing version '{1}' for workload manifest ID '{0}'</source>
|
||||
<target state="new">Error parsing version '{1}' for workload manifest ID '{0}'</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ManifestDependencyMissing">
|
||||
<source>Did not find workload manifest dependency '{0}' required by manifest '{1}' [{2}]</source>
|
||||
<target state="translated">未找到清单“{1}”[{2}] 所需的工作负载清单依赖项“{0}”</target>
|
||||
|
@ -102,6 +107,11 @@
|
|||
<target state="translated">找不到指定的工作负荷清单: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="SpecifiedWorkloadSetNotFound">
|
||||
<source>Specified workload set was not found: {0}</source>
|
||||
<target state="new">Specified workload set was not found: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="UnexpectedTokenAtOffset">
|
||||
<source>Unexpected token '{0}' at offset {1}</source>
|
||||
<target state="translated">偏移为 {1} 时意外出现的标记“{0}”</target>
|
||||
|
|
|
@ -62,6 +62,11 @@
|
|||
<target state="translated">無效的版本: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="InvalidVersionForWorkload">
|
||||
<source>Error parsing version '{1}' for workload manifest ID '{0}'</source>
|
||||
<target state="new">Error parsing version '{1}' for workload manifest ID '{0}'</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ManifestDependencyMissing">
|
||||
<source>Did not find workload manifest dependency '{0}' required by manifest '{1}' [{2}]</source>
|
||||
<target state="translated">找不到資訊清單 '{1}' [{2}] 所需的工作負載資訊清單相依性 '{0}'</target>
|
||||
|
@ -102,6 +107,11 @@
|
|||
<target state="translated">找不到指定的工作負載資訊清單: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="SpecifiedWorkloadSetNotFound">
|
||||
<source>Specified workload set was not found: {0}</source>
|
||||
<target state="new">Specified workload set was not found: {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="UnexpectedTokenAtOffset">
|
||||
<source>Unexpected token '{0}' at offset {1}</source>
|
||||
<target state="translated">位移 {1} 有未預期的權杖 '{0}'</target>
|
||||
|
|
|
@ -1014,7 +1014,7 @@ The following are names of parameters or literal values and should not be transl
|
|||
</trans-unit>
|
||||
<trans-unit id="WorkloadIsEol">
|
||||
<source>NETSDK1202: The workload '{0}' is out of support and will not receive security updates in the future. Please refer to {1} for more information about the support policy.</source>
|
||||
<target state="new">NETSDK1202: The workload '{0}' is out of support and will not receive security updates in the future. Please refer to {1} for more information about the support policy.</target>
|
||||
<target state="translated">NETSDK1202: Architektura {0} se nepodporuje a v budoucnu už nebude dostávat aktualizace zabezpečení. Další informace o zásadách podpory najdete tady: {1}.</target>
|
||||
<note>{StrBegin="NETSDK1202: "}</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="WorkloadNotAvailable">
|
||||
|
|
|
@ -1014,7 +1014,7 @@ The following are names of parameters or literal values and should not be transl
|
|||
</trans-unit>
|
||||
<trans-unit id="WorkloadIsEol">
|
||||
<source>NETSDK1202: The workload '{0}' is out of support and will not receive security updates in the future. Please refer to {1} for more information about the support policy.</source>
|
||||
<target state="new">NETSDK1202: The workload '{0}' is out of support and will not receive security updates in the future. Please refer to {1} for more information about the support policy.</target>
|
||||
<target state="translated">NETSDK1202: Die Workload „{0}“ wird nicht mehr unterstützt und erhält in Zukunft keine Sicherheitsupdates mehr. Weitere Informationen zur Supportrichtlinie finden Sie unter „{1}“.</target>
|
||||
<note>{StrBegin="NETSDK1202: "}</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="WorkloadNotAvailable">
|
||||
|
|
|
@ -1014,7 +1014,7 @@ The following are names of parameters or literal values and should not be transl
|
|||
</trans-unit>
|
||||
<trans-unit id="WorkloadIsEol">
|
||||
<source>NETSDK1202: The workload '{0}' is out of support and will not receive security updates in the future. Please refer to {1} for more information about the support policy.</source>
|
||||
<target state="new">NETSDK1202: The workload '{0}' is out of support and will not receive security updates in the future. Please refer to {1} for more information about the support policy.</target>
|
||||
<target state="translated">NETSDK1202: La carga de trabajo "{0}" está fuera de soporte y no recibirá actualizaciones de seguridad en el futuro. Consulte {1} más información sobre la directiva de soporte.</target>
|
||||
<note>{StrBegin="NETSDK1202: "}</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="WorkloadNotAvailable">
|
||||
|
|
|
@ -1014,7 +1014,7 @@ The following are names of parameters or literal values and should not be transl
|
|||
</trans-unit>
|
||||
<trans-unit id="WorkloadIsEol">
|
||||
<source>NETSDK1202: The workload '{0}' is out of support and will not receive security updates in the future. Please refer to {1} for more information about the support policy.</source>
|
||||
<target state="new">NETSDK1202: The workload '{0}' is out of support and will not receive security updates in the future. Please refer to {1} for more information about the support policy.</target>
|
||||
<target state="translated">NETSDK1202: La charge de travail '{0}' n’est pas prise en charge et ne recevra pas les mises à jour de sécurité. Consultez {1} pour plus d’informations sur la stratégie de support.</target>
|
||||
<note>{StrBegin="NETSDK1202: "}</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="WorkloadNotAvailable">
|
||||
|
|
|
@ -1014,7 +1014,7 @@ The following are names of parameters or literal values and should not be transl
|
|||
</trans-unit>
|
||||
<trans-unit id="WorkloadIsEol">
|
||||
<source>NETSDK1202: The workload '{0}' is out of support and will not receive security updates in the future. Please refer to {1} for more information about the support policy.</source>
|
||||
<target state="new">NETSDK1202: The workload '{0}' is out of support and will not receive security updates in the future. Please refer to {1} for more information about the support policy.</target>
|
||||
<target state="translated">NETSDK1202: il carico di lavoro '{0}' non è supportato e non riceverà gli aggiornamenti della sicurezza in futuro. Per altre informazioni sui criteri di supporto, vedere {1} .</target>
|
||||
<note>{StrBegin="NETSDK1202: "}</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="WorkloadNotAvailable">
|
||||
|
|
|
@ -1014,7 +1014,7 @@ The following are names of parameters or literal values and should not be transl
|
|||
</trans-unit>
|
||||
<trans-unit id="WorkloadIsEol">
|
||||
<source>NETSDK1202: The workload '{0}' is out of support and will not receive security updates in the future. Please refer to {1} for more information about the support policy.</source>
|
||||
<target state="new">NETSDK1202: The workload '{0}' is out of support and will not receive security updates in the future. Please refer to {1} for more information about the support policy.</target>
|
||||
<target state="translated">NETSDK1202: ワークロード '{0}' はサポートされていません。今後、セキュリティ更新プログラムを受け取ることはありません。サポート ポリシーの詳細については、{1} をご覧ください。</target>
|
||||
<note>{StrBegin="NETSDK1202: "}</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="WorkloadNotAvailable">
|
||||
|
|
|
@ -1014,7 +1014,7 @@ The following are names of parameters or literal values and should not be transl
|
|||
</trans-unit>
|
||||
<trans-unit id="WorkloadIsEol">
|
||||
<source>NETSDK1202: The workload '{0}' is out of support and will not receive security updates in the future. Please refer to {1} for more information about the support policy.</source>
|
||||
<target state="new">NETSDK1202: The workload '{0}' is out of support and will not receive security updates in the future. Please refer to {1} for more information about the support policy.</target>
|
||||
<target state="translated">NETSDK1202: '{0}' 워크로드는 지원되지 않으며 향후 보안 업데이트를 받지 않습니다. 지원 정책에 대한 자세한 내용은 {1}을(를) 참조하세요.</target>
|
||||
<note>{StrBegin="NETSDK1202: "}</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="WorkloadNotAvailable">
|
||||
|
|
|
@ -1014,7 +1014,7 @@ The following are names of parameters or literal values and should not be transl
|
|||
</trans-unit>
|
||||
<trans-unit id="WorkloadIsEol">
|
||||
<source>NETSDK1202: The workload '{0}' is out of support and will not receive security updates in the future. Please refer to {1} for more information about the support policy.</source>
|
||||
<target state="new">NETSDK1202: The workload '{0}' is out of support and will not receive security updates in the future. Please refer to {1} for more information about the support policy.</target>
|
||||
<target state="translated">NETSDK1202: Obciążenie „{0}” nie jest obsługiwane i nie będzie otrzymywać aktualizacji zabezpieczeń w przyszłości. Aby uzyskać więcej informacji na temat zasad pomocy technicznej, zapoznaj się z {1} .</target>
|
||||
<note>{StrBegin="NETSDK1202: "}</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="WorkloadNotAvailable">
|
||||
|
|
|
@ -1014,7 +1014,7 @@ The following are names of parameters or literal values and should not be transl
|
|||
</trans-unit>
|
||||
<trans-unit id="WorkloadIsEol">
|
||||
<source>NETSDK1202: The workload '{0}' is out of support and will not receive security updates in the future. Please refer to {1} for more information about the support policy.</source>
|
||||
<target state="new">NETSDK1202: The workload '{0}' is out of support and will not receive security updates in the future. Please refer to {1} for more information about the support policy.</target>
|
||||
<target state="translated">NETSDK1202: a carga de trabalho '{0}' está sem suporte e não receberá atualizações de segurança no futuro. Consulte o {1} para obter mais informações sobre a política de suporte.</target>
|
||||
<note>{StrBegin="NETSDK1202: "}</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="WorkloadNotAvailable">
|
||||
|
|
|
@ -1014,7 +1014,7 @@ The following are names of parameters or literal values and should not be transl
|
|||
</trans-unit>
|
||||
<trans-unit id="WorkloadIsEol">
|
||||
<source>NETSDK1202: The workload '{0}' is out of support and will not receive security updates in the future. Please refer to {1} for more information about the support policy.</source>
|
||||
<target state="new">NETSDK1202: The workload '{0}' is out of support and will not receive security updates in the future. Please refer to {1} for more information about the support policy.</target>
|
||||
<target state="translated">NETSDK1202: рабочая нагрузка "{0}" не поддерживается, для нее не будут выпускаться обновления системы безопасности. Дополнительные сведения о политике поддержки: {1}.</target>
|
||||
<note>{StrBegin="NETSDK1202: "}</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="WorkloadNotAvailable">
|
||||
|
|
|
@ -1014,7 +1014,7 @@ The following are names of parameters or literal values and should not be transl
|
|||
</trans-unit>
|
||||
<trans-unit id="WorkloadIsEol">
|
||||
<source>NETSDK1202: The workload '{0}' is out of support and will not receive security updates in the future. Please refer to {1} for more information about the support policy.</source>
|
||||
<target state="new">NETSDK1202: The workload '{0}' is out of support and will not receive security updates in the future. Please refer to {1} for more information about the support policy.</target>
|
||||
<target state="translated">NETSDK1202: '{0}' iş yükü destek kapsamı dışında olduğu için gelecekte güvenlik güncelleştirmeleri almayacak. Destek ilkesi hakkında daha fazla bilgi edinmek için lütfen şuraya bakın: {1}.</target>
|
||||
<note>{StrBegin="NETSDK1202: "}</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="WorkloadNotAvailable">
|
||||
|
|
|
@ -1014,7 +1014,7 @@ The following are names of parameters or literal values and should not be transl
|
|||
</trans-unit>
|
||||
<trans-unit id="WorkloadIsEol">
|
||||
<source>NETSDK1202: The workload '{0}' is out of support and will not receive security updates in the future. Please refer to {1} for more information about the support policy.</source>
|
||||
<target state="new">NETSDK1202: The workload '{0}' is out of support and will not receive security updates in the future. Please refer to {1} for more information about the support policy.</target>
|
||||
<target state="translated">NETSDK1202: 工作负载“{0}”已失去支持,并且将来不会收到安全更新。有关支持政策的详细信息,请参阅 {1}。</target>
|
||||
<note>{StrBegin="NETSDK1202: "}</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="WorkloadNotAvailable">
|
||||
|
|
|
@ -1014,7 +1014,7 @@ The following are names of parameters or literal values and should not be transl
|
|||
</trans-unit>
|
||||
<trans-unit id="WorkloadIsEol">
|
||||
<source>NETSDK1202: The workload '{0}' is out of support and will not receive security updates in the future. Please refer to {1} for more information about the support policy.</source>
|
||||
<target state="new">NETSDK1202: The workload '{0}' is out of support and will not receive security updates in the future. Please refer to {1} for more information about the support policy.</target>
|
||||
<target state="translated">NETSDK1202: 已不支援目標工作負載 '{0}',未來將不會再收到任何安全性更新。如需支援原則的詳細資訊,請參閱 {1}。</target>
|
||||
<note>{StrBegin="NETSDK1202: "}</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="WorkloadNotAvailable">
|
||||
|
|
|
@ -457,12 +457,11 @@ Copyright (c) .NET Foundation. All rights reserved.
|
|||
<Output TaskParameter="FullFrameworkReferenceAssemblyPaths" PropertyName="_FullFrameworkReferenceAssemblyPaths"/>
|
||||
</GetReferenceAssemblyPaths>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<_ExistingReferenceAssembliesPackageReference Include="@(PackageReference)" Condition="'%(PackageReference.Identity)' == 'Microsoft.NETFramework.ReferenceAssemblies'"/>
|
||||
|
||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="$(MicrosoftNETFrameworkReferenceAssembliesLatestPackageVersion)" IsImplicitlyDefined="true" PrivateAssets="All"
|
||||
Condition="'$(_FullFrameworkReferenceAssemblyPaths)' == '' and '@(_ExistingReferenceAssembliesPackageReference)' == ''"/>
|
||||
Condition="('$(_FullFrameworkReferenceAssemblyPaths)' == '' or $(_FullFrameworkReferenceAssemblyPaths.Contains('microsoft.netframework.referenceassemblies'))) and '@(_ExistingReferenceAssembliesPackageReference)' == ''"/>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
|
|
|
@ -10,6 +10,9 @@ using Microsoft.NET.Build.Containers.UnitTests;
|
|||
using Microsoft.NET.TestFramework.Assertions;
|
||||
using Microsoft.NET.TestFramework.Commands;
|
||||
using Microsoft.NET.TestFramework;
|
||||
using FakeItEasy;
|
||||
using Microsoft.Build.Framework;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Microsoft.NET.Build.Containers.Tasks.IntegrationTests;
|
||||
|
||||
|
@ -26,8 +29,7 @@ public class CreateNewImageTests
|
|||
[DockerAvailableFact]
|
||||
public void CreateNewImage_Baseline()
|
||||
{
|
||||
DirectoryInfo newProjectDir = new DirectoryInfo(Path.Combine(TestSettings.TestArtifactsDirectory, nameof(CreateNewImage_Baseline)));
|
||||
|
||||
DirectoryInfo newProjectDir = new(GetTestDirectoryName());
|
||||
if (newProjectDir.Exists)
|
||||
{
|
||||
newProjectDir.Delete(recursive: true);
|
||||
|
@ -46,28 +48,33 @@ public class CreateNewImageTests
|
|||
.Execute()
|
||||
.Should().Pass();
|
||||
|
||||
CreateNewImage task = new CreateNewImage();
|
||||
CreateNewImage task = new();
|
||||
|
||||
(IBuildEngine buildEngine, List<string?> errors) = SetupBuildEngine();
|
||||
task.BuildEngine = buildEngine;
|
||||
|
||||
task.BaseRegistry = "mcr.microsoft.com";
|
||||
task.BaseImageName = "dotnet/runtime";
|
||||
task.BaseImageTag = "7.0";
|
||||
|
||||
task.OutputRegistry = "localhost:5010";
|
||||
task.LocalRegistry = "Docker";
|
||||
task.PublishDirectory = Path.Combine(newProjectDir.FullName, "bin", "Release", ToolsetInfo.CurrentTargetFramework, "linux-arm64", "publish");
|
||||
task.ImageName = "dotnet/testimage";
|
||||
task.Repository = "dotnet/create-new-image-baseline";
|
||||
task.ImageTags = new[] { "latest" };
|
||||
task.WorkingDirectory = "app/";
|
||||
task.ContainerRuntimeIdentifier = "linux-arm64";
|
||||
task.Entrypoint = new TaskItem[] { new("dotnet"), new("build") };
|
||||
task.RuntimeIdentifierGraphPath = ToolsetUtils.GetRuntimeGraphFilePath();
|
||||
|
||||
Assert.True(task.Execute());
|
||||
Assert.True(task.Execute(), FormatBuildMessages(errors));
|
||||
newProjectDir.Delete(true);
|
||||
}
|
||||
|
||||
[DockerAvailableFact]
|
||||
public void ParseContainerProperties_EndToEnd()
|
||||
{
|
||||
DirectoryInfo newProjectDir = new DirectoryInfo(Path.Combine(TestSettings.TestArtifactsDirectory, nameof(ParseContainerProperties_EndToEnd)));
|
||||
DirectoryInfo newProjectDir = new(GetTestDirectoryName());
|
||||
|
||||
if (newProjectDir.Exists)
|
||||
{
|
||||
|
@ -87,34 +94,40 @@ public class CreateNewImageTests
|
|||
.Execute()
|
||||
.Should().Pass();
|
||||
|
||||
ParseContainerProperties pcp = new ParseContainerProperties();
|
||||
ParseContainerProperties pcp = new();
|
||||
(IBuildEngine buildEngine, List<string?> errors) = SetupBuildEngine();
|
||||
pcp.BuildEngine = buildEngine;
|
||||
|
||||
pcp.FullyQualifiedBaseImageName = "mcr.microsoft.com/dotnet/runtime:7.0";
|
||||
pcp.ContainerRegistry = "localhost:5010";
|
||||
pcp.ContainerImageName = "dotnet/testimage";
|
||||
pcp.ContainerRepository = "dotnet/testimage";
|
||||
pcp.ContainerImageTags = new[] { "5.0", "latest" };
|
||||
|
||||
Assert.True(pcp.Execute());
|
||||
Assert.True(pcp.Execute(), FormatBuildMessages(errors));
|
||||
Assert.Equal("mcr.microsoft.com", pcp.ParsedContainerRegistry);
|
||||
Assert.Equal("dotnet/runtime", pcp.ParsedContainerImage);
|
||||
Assert.Equal("7.0", pcp.ParsedContainerTag);
|
||||
|
||||
Assert.Equal("dotnet/testimage", pcp.NewContainerImageName);
|
||||
Assert.Equal("dotnet/testimage", pcp.NewContainerRepository);
|
||||
pcp.NewContainerTags.Should().BeEquivalentTo(new[] { "5.0", "latest" });
|
||||
|
||||
CreateNewImage cni = new CreateNewImage();
|
||||
CreateNewImage cni = new();
|
||||
(buildEngine, errors) = SetupBuildEngine();
|
||||
cni.BuildEngine = buildEngine;
|
||||
|
||||
cni.BaseRegistry = pcp.ParsedContainerRegistry;
|
||||
cni.BaseImageName = pcp.ParsedContainerImage;
|
||||
cni.BaseImageTag = pcp.ParsedContainerTag;
|
||||
cni.ImageName = pcp.NewContainerImageName;
|
||||
cni.Repository = pcp.NewContainerRepository;
|
||||
cni.OutputRegistry = "localhost:5010";
|
||||
cni.PublishDirectory = Path.Combine(newProjectDir.FullName, "bin", "release", ToolsetInfo.CurrentTargetFramework);
|
||||
cni.WorkingDirectory = "app/";
|
||||
cni.Entrypoint = new TaskItem[] { new("ParseContainerProperties_EndToEnd") };
|
||||
cni.Entrypoint = new TaskItem[] { new(newProjectDir.Name) };
|
||||
cni.ImageTags = pcp.NewContainerTags;
|
||||
cni.ContainerRuntimeIdentifier = "linux-x64";
|
||||
cni.RuntimeIdentifierGraphPath = ToolsetUtils.GetRuntimeGraphFilePath();
|
||||
|
||||
Assert.True(cni.Execute());
|
||||
Assert.True(cni.Execute(), FormatBuildMessages(errors));
|
||||
newProjectDir.Delete(true);
|
||||
}
|
||||
|
||||
|
@ -124,7 +137,7 @@ public class CreateNewImageTests
|
|||
[DockerAvailableFact]
|
||||
public void Tasks_EndToEnd_With_EnvironmentVariable_Validation()
|
||||
{
|
||||
DirectoryInfo newProjectDir = new DirectoryInfo(Path.Combine(TestSettings.TestArtifactsDirectory, nameof(Tasks_EndToEnd_With_EnvironmentVariable_Validation)));
|
||||
DirectoryInfo newProjectDir = new(GetTestDirectoryName());
|
||||
|
||||
if (newProjectDir.Exists)
|
||||
{
|
||||
|
@ -146,10 +159,13 @@ public class CreateNewImageTests
|
|||
.Execute()
|
||||
.Should().Pass();
|
||||
|
||||
ParseContainerProperties pcp = new ParseContainerProperties();
|
||||
ParseContainerProperties pcp = new();
|
||||
(IBuildEngine buildEngine, List<string?> errors) = SetupBuildEngine();
|
||||
pcp.BuildEngine = buildEngine;
|
||||
|
||||
pcp.FullyQualifiedBaseImageName = $"mcr.microsoft.com/{DockerRegistryManager.RuntimeBaseImage}:{DockerRegistryManager.Net8PreviewImageTag}";
|
||||
pcp.ContainerRegistry = "";
|
||||
pcp.ContainerImageName = "dotnet/envvarvalidation";
|
||||
pcp.ContainerRepository = "dotnet/envvarvalidation";
|
||||
pcp.ContainerImageTag = "latest";
|
||||
|
||||
Dictionary<string, string> dict = new Dictionary<string, string>();
|
||||
|
@ -157,34 +173,37 @@ public class CreateNewImageTests
|
|||
|
||||
pcp.ContainerEnvironmentVariables = new[] { new TaskItem("B@dEnv.Var", dict), new TaskItem("GoodEnvVar", dict) };
|
||||
|
||||
Assert.True(pcp.Execute());
|
||||
Assert.True(pcp.Execute(), FormatBuildMessages(errors));
|
||||
Assert.Equal("mcr.microsoft.com", pcp.ParsedContainerRegistry);
|
||||
Assert.Equal("dotnet/runtime", pcp.ParsedContainerImage);
|
||||
Assert.Equal(DockerRegistryManager.Net8PreviewImageTag, pcp.ParsedContainerTag);
|
||||
Assert.Single(pcp.NewContainerEnvironmentVariables);
|
||||
Assert.Equal("Foo", pcp.NewContainerEnvironmentVariables[0].GetMetadata("Value"));
|
||||
|
||||
Assert.Equal("dotnet/envvarvalidation", pcp.NewContainerImageName);
|
||||
Assert.Equal("dotnet/envvarvalidation", pcp.NewContainerRepository);
|
||||
Assert.Equal("latest", pcp.NewContainerTags[0]);
|
||||
|
||||
CreateNewImage cni = new CreateNewImage();
|
||||
CreateNewImage cni = new();
|
||||
(buildEngine, errors) = SetupBuildEngine();
|
||||
cni.BuildEngine = buildEngine;
|
||||
|
||||
cni.BaseRegistry = pcp.ParsedContainerRegistry;
|
||||
cni.BaseImageName = pcp.ParsedContainerImage;
|
||||
cni.BaseImageTag = pcp.ParsedContainerTag;
|
||||
cni.ImageName = pcp.NewContainerImageName;
|
||||
cni.Repository = pcp.NewContainerRepository;
|
||||
cni.OutputRegistry = pcp.NewContainerRegistry;
|
||||
cni.PublishDirectory = Path.Combine(newProjectDir.FullName, "bin", "release", ToolsetInfo.CurrentTargetFramework, "linux-x64");
|
||||
cni.WorkingDirectory = "/app";
|
||||
cni.Entrypoint = new TaskItem[] { new("/app/Tasks_EndToEnd_With_EnvironmentVariable_Validation") };
|
||||
cni.Entrypoint = new TaskItem[] { new($"/app/{newProjectDir.Name}") };
|
||||
cni.ImageTags = pcp.NewContainerTags;
|
||||
cni.ContainerEnvironmentVariables = pcp.NewContainerEnvironmentVariables;
|
||||
cni.ContainerRuntimeIdentifier = "linux-x64";
|
||||
cni.RuntimeIdentifierGraphPath = ToolsetUtils.GetRuntimeGraphFilePath();
|
||||
cni.LocalRegistry = global::Microsoft.NET.Build.Containers.KnownLocalRegistryTypes.Docker;
|
||||
|
||||
Assert.True(cni.Execute());
|
||||
Assert.True(cni.Execute(), FormatBuildMessages(errors));
|
||||
|
||||
ContainerCli.RunCommand(_testOutput, "--rm", $"{pcp.NewContainerImageName}:latest")
|
||||
ContainerCli.RunCommand(_testOutput, "--rm", $"{pcp.NewContainerRepository}:latest")
|
||||
.Execute()
|
||||
.Should().Pass()
|
||||
.And.HaveStdOut("Foo");
|
||||
|
@ -246,7 +265,7 @@ public class CreateNewImageTests
|
|||
|
||||
task.OutputRegistry = "localhost:5010";
|
||||
task.PublishDirectory = Path.Combine(newProjectDir.FullName, "bin", "Release", ToolsetInfo.CurrentTargetFramework, "linux-x64", "publish");
|
||||
task.ImageName = AppImage;
|
||||
task.Repository = AppImage;
|
||||
task.ImageTags = new[] { "latest" };
|
||||
task.WorkingDirectory = "app/";
|
||||
task.ContainerRuntimeIdentifier = "linux-x64";
|
||||
|
@ -266,4 +285,19 @@ public class CreateNewImageTests
|
|||
|
||||
Assert.Equal(RootlessUser, imageBuilder.BaseImageConfig.User);
|
||||
}
|
||||
|
||||
private static (IBuildEngine buildEngine, List<string?> errors) SetupBuildEngine()
|
||||
{
|
||||
List<string?> errors = new();
|
||||
IBuildEngine buildEngine = A.Fake<IBuildEngine>();
|
||||
A.CallTo(() => buildEngine.LogWarningEvent(A<BuildWarningEventArgs>.Ignored)).Invokes((BuildWarningEventArgs e) => errors.Add(e.Message));
|
||||
A.CallTo(() => buildEngine.LogErrorEvent(A<BuildErrorEventArgs>.Ignored)).Invokes((BuildErrorEventArgs e) => errors.Add(e.Message));
|
||||
A.CallTo(() => buildEngine.LogMessageEvent(A<BuildMessageEventArgs>.Ignored)).Invokes((BuildMessageEventArgs e) => errors.Add(e.Message));
|
||||
|
||||
return (buildEngine, errors);
|
||||
}
|
||||
|
||||
private static string GetTestDirectoryName([CallerMemberName]string testName = "DefaultTest") => Path.Combine(TestSettings.TestArtifactsDirectory, testName + "_" + DateTime.Now.ToString("yyyyMMddHHmmss"));
|
||||
|
||||
private static string FormatBuildMessages(List<string?> messages) => string.Join("\r\n", messages);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ public class EndToEndTests
|
|||
|
||||
public static string NewImageName([CallerMemberName] string callerMemberName = "")
|
||||
{
|
||||
bool normalized = ContainerHelpers.NormalizeImageName(callerMemberName, out string? normalizedName);
|
||||
bool normalized = ContainerHelpers.NormalizeRepository(callerMemberName, out string? normalizedName);
|
||||
if (!normalized)
|
||||
{
|
||||
return normalizedName!;
|
||||
|
@ -228,7 +228,7 @@ public class EndToEndTests
|
|||
"/p:runtimeidentifier=linux-x64",
|
||||
$"/p:ContainerBaseImage={DockerRegistryManager.FullyQualifiedBaseImageAspNet}",
|
||||
$"/p:ContainerRegistry={DockerRegistryManager.LocalRegistry}",
|
||||
$"/p:ContainerImageName={imageName}",
|
||||
$"/p:ContainerRepository={imageName}",
|
||||
$"/p:Version={imageTag}",
|
||||
$"/p:RuntimeFrameworkVersion=8.0.0-preview.3.23174.8")
|
||||
.WithEnvironmentVariable("NUGET_PACKAGES", privateNuGetAssets.FullName)
|
||||
|
@ -366,7 +366,7 @@ public class EndToEndTests
|
|||
"/p:runtimeidentifier=linux-x64",
|
||||
$"/p:ContainerBaseImage={DockerRegistryManager.FullyQualifiedBaseImageAspNet}",
|
||||
$"/p:ContainerRegistry={DockerRegistryManager.LocalRegistry}",
|
||||
$"/p:ContainerImageName={imageName}",
|
||||
$"/p:ContainerRepository={imageName}",
|
||||
$"/p:RuntimeFrameworkVersion=8.0.0-preview.3.23174.8",
|
||||
$"/p:Version={imageTag}")
|
||||
.WithEnvironmentVariable("NUGET_PACKAGES", privateNuGetAssets.FullName)
|
||||
|
|
|
@ -46,9 +46,9 @@ public class CreateNewImageToolTaskTests
|
|||
task.BaseImageName = "MyBaseImageName";
|
||||
|
||||
e = Assert.Throws<InvalidOperationException>(() => task.GenerateCommandLineCommandsInt());
|
||||
Assert.Equal("CONTAINER4001: Required property 'ImageName' was not set or empty.", e.Message);
|
||||
Assert.Equal("CONTAINER4001: Required property 'Repository' was not set or empty.", e.Message);
|
||||
|
||||
task.ImageName = "MyImageName";
|
||||
task.Repository = "MyImageName";
|
||||
|
||||
e = Assert.Throws<InvalidOperationException>(() => task.GenerateCommandLineCommandsInt());
|
||||
Assert.Equal("CONTAINER4001: Required property 'WorkingDirectory' was not set or empty.", e.Message);
|
||||
|
@ -58,7 +58,7 @@ public class CreateNewImageToolTaskTests
|
|||
e = Assert.Throws<InvalidOperationException>(() => task.GenerateCommandLineCommandsInt());
|
||||
Assert.Equal("CONTAINER4002: Required 'Entrypoint' items were not set.", e.Message);
|
||||
|
||||
task.Entrypoint = new[] { new TaskItem("") };
|
||||
task.Entrypoint = new[] { new TaskItem("") };
|
||||
|
||||
e = Assert.Throws<InvalidOperationException>(() => task.GenerateCommandLineCommandsInt());
|
||||
Assert.Equal("CONTAINER4003: Required 'Entrypoint' items contain empty items.", e.Message);
|
||||
|
@ -88,7 +88,7 @@ public class CreateNewImageToolTaskTests
|
|||
task.PublishDirectory = publishDir.FullName;
|
||||
task.BaseRegistry = "MyBaseRegistry";
|
||||
task.BaseImageName = "MyBaseImageName";
|
||||
task.ImageName = "MyImageName";
|
||||
task.Repository = "MyImageName";
|
||||
task.WorkingDirectory = "MyWorkingDirectory";
|
||||
task.Entrypoint = new[] { new TaskItem("MyEntryPoint") };
|
||||
|
||||
|
@ -103,7 +103,7 @@ public class CreateNewImageToolTaskTests
|
|||
else
|
||||
{
|
||||
Assert.DoesNotContain("--baseimagetag", args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -119,7 +119,7 @@ public class CreateNewImageToolTaskTests
|
|||
task.PublishDirectory = publishDir.FullName;
|
||||
task.BaseRegistry = "MyBaseRegistry";
|
||||
task.BaseImageName = "MyBaseImageName";
|
||||
task.ImageName = "MyImageName";
|
||||
task.Repository = "MyImageName";
|
||||
task.WorkingDirectory = "MyWorkingDirectory";
|
||||
task.Entrypoint = new[] { new TaskItem("MyEntryPoint") };
|
||||
|
||||
|
@ -149,7 +149,7 @@ public class CreateNewImageToolTaskTests
|
|||
task.PublishDirectory = publishDir.FullName;
|
||||
task.BaseRegistry = "MyBaseRegistry";
|
||||
task.BaseImageName = "MyBaseImageName";
|
||||
task.ImageName = "MyImageName";
|
||||
task.Repository = "MyImageName";
|
||||
task.WorkingDirectory = "MyWorkingDirectory";
|
||||
task.Entrypoint = new[] { new TaskItem("MyEntryPoint") };
|
||||
|
||||
|
@ -178,7 +178,7 @@ public class CreateNewImageToolTaskTests
|
|||
task.PublishDirectory = publishDir.FullName;
|
||||
task.BaseRegistry = "MyBaseRegistry";
|
||||
task.BaseImageName = "MyBaseImageName";
|
||||
task.ImageName = "MyImageName";
|
||||
task.Repository = "MyImageName";
|
||||
task.WorkingDirectory = "MyWorkingDirectory";
|
||||
task.Entrypoint = new[] { new TaskItem("MyEntryPoint") };
|
||||
|
||||
|
@ -211,7 +211,7 @@ public class CreateNewImageToolTaskTests
|
|||
task.PublishDirectory = publishDir.FullName;
|
||||
task.BaseRegistry = "MyBaseRegistry";
|
||||
task.BaseImageName = "MyBaseImageName";
|
||||
task.ImageName = "MyImageName";
|
||||
task.Repository = "MyImageName";
|
||||
task.WorkingDirectory = "MyWorkingDirectory";
|
||||
task.Entrypoint = new[] { new TaskItem("MyEntryPoint") };
|
||||
|
||||
|
@ -257,7 +257,7 @@ public class CreateNewImageToolTaskTests
|
|||
task.PublishDirectory = publishDir.FullName;
|
||||
task.BaseRegistry = "MyBaseRegistry";
|
||||
task.BaseImageName = "MyBaseImageName";
|
||||
task.ImageName = "MyImageName";
|
||||
task.Repository = "MyImageName";
|
||||
task.WorkingDirectory = "MyWorkingDirectory";
|
||||
task.Entrypoint = new[] { new TaskItem("MyEntryPoint") };
|
||||
|
||||
|
@ -304,7 +304,7 @@ public class CreateNewImageToolTaskTests
|
|||
task.PublishDirectory = publishDir.FullName;
|
||||
task.BaseRegistry = "MyBaseRegistry";
|
||||
task.BaseImageName = "MyBaseImageName";
|
||||
task.ImageName = "MyImageName";
|
||||
task.Repository = "MyImageName";
|
||||
task.WorkingDirectory = "MyWorkingDirectory";
|
||||
task.Entrypoint = new[] { new TaskItem("MyEntryPoint") };
|
||||
|
||||
|
@ -348,7 +348,7 @@ public class CreateNewImageToolTaskTests
|
|||
task.PublishDirectory = publishDir.FullName;
|
||||
task.BaseRegistry = "MyBaseRegistry";
|
||||
task.BaseImageName = "MyBaseImageName";
|
||||
task.ImageName = "MyImageName";
|
||||
task.Repository = "MyImageName";
|
||||
task.WorkingDirectory = "MyWorkingDirectory";
|
||||
task.Entrypoint = new[] { new TaskItem("MyEntryPoint") };
|
||||
|
||||
|
@ -385,7 +385,7 @@ public class CreateNewImageToolTaskTests
|
|||
task.PublishDirectory = publishDir.FullName;
|
||||
task.BaseRegistry = "MyBaseRegistry";
|
||||
task.BaseImageName = "MyBaseImageName";
|
||||
task.ImageName = "MyImageName";
|
||||
task.Repository = "MyImageName";
|
||||
task.WorkingDirectory = "MyWorkingDirectory";
|
||||
task.Entrypoint = new[] { new TaskItem("MyEntryPoint") };
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="$(MicrosoftBuildTasksCorePackageVersion)"/>
|
||||
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="$(MicrosoftBuildUtilitiesCorePackageVersion)"/>
|
||||
<PackageReference Include="Microsoft.Build" Version="$(MicrosoftBuildPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Build.Framework" Version="$(MicrosoftBuildFrameworkPackageVersion)"/>
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.IO.Compression;
|
||||
using System.Xml.Linq;
|
||||
using FluentAssertions;
|
||||
using Microsoft.NET.TestFramework;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.NET.Build.Containers.IntegrationTests;
|
||||
|
||||
public class PackageTests
|
||||
{
|
||||
[Fact]
|
||||
public void SanityTest_ContainerizeDependencies()
|
||||
{
|
||||
IReadOnlyList<string> knownPackageReferences = new List<string>()
|
||||
{
|
||||
"System.CommandLine"
|
||||
};
|
||||
IReadOnlyList<string> knownProjectReferences = new List<string>()
|
||||
{
|
||||
"..\\Microsoft.NET.Build.Containers\\Microsoft.NET.Build.Containers.csproj"
|
||||
};
|
||||
|
||||
string projectFilePath = Path.Combine(TestContext.Current.TestExecutionDirectory, "Container", "ProjectFiles", "containerize.csproj");
|
||||
XDocument project = XDocument.Load(projectFilePath);
|
||||
XNamespace ns = project.Root?.Name.Namespace ?? throw new InvalidOperationException("Project file is empty");
|
||||
|
||||
IEnumerable<string?> packageReferences = project.Descendants().Where(element => element.Name.Equals(ns + "PackageReference")).Select(element => element.Attribute("Include")?.Value);
|
||||
packageReferences.Should().BeEquivalentTo(knownPackageReferences, $"Known package references for containerize project are different from actual. Check if this is expected. If the new package reference is expected, add it to {nameof(knownPackageReferences)} and verify they are included to NuGet package in package.csproj correctly");
|
||||
|
||||
IEnumerable<string?> projectReferences = project.Descendants().Where(element => element.Name.Equals(ns + "ProjectReference")).Select(element => element.Attribute("Include")?.Value);
|
||||
projectReferences.Should().BeEquivalentTo(knownProjectReferences, $"Known project references for containerize project are different from actual. Check if this is expected. If the new project reference is expected, add it to {nameof(knownProjectReferences)} and verify they are included to NuGet package in package.csproj correctly");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SanityTest_NET_Build_ContainersDependencies()
|
||||
{
|
||||
IReadOnlyList<string> knownPackageReferences = new List<string>()
|
||||
{
|
||||
"Microsoft.Build.Utilities.Core",
|
||||
"Microsoft.CodeAnalysis.PublicApiAnalyzers",
|
||||
"Nuget.Packaging",
|
||||
"Valleysoft.DockerCredsProvider"
|
||||
};
|
||||
IReadOnlyList<string> knownProjectReferences = new List<string>()
|
||||
{
|
||||
"..\\..\\Cli\\Microsoft.DotNet.Cli.Utils\\Microsoft.DotNet.Cli.Utils.csproj"
|
||||
};
|
||||
|
||||
string projectFilePath = Path.Combine(TestContext.Current.TestExecutionDirectory, "Container", "ProjectFiles", "Microsoft.NET.Build.Containers.csproj");
|
||||
XDocument project = XDocument.Load(projectFilePath);
|
||||
XNamespace ns = project.Root?.Name.Namespace ?? throw new InvalidOperationException("Project file is empty");
|
||||
|
||||
IEnumerable<string?> packageReferences = project.Descendants().Where(element => element.Name.Equals(ns + "PackageReference")).Select(element => element.Attribute("Include")?.Value);
|
||||
packageReferences.Should().BeEquivalentTo(knownPackageReferences, $"Known package references for Microsoft.NET.Build.Containers project are different from actual. Check if this is expected. If the new package reference is expected, add it to {nameof(knownPackageReferences)} and verify they are included to NuGet package in package.csproj correctly");
|
||||
|
||||
IEnumerable<string?> projectReferences = project.Descendants().Where(element => element.Name.Equals(ns + "ProjectReference")).Select(element => element.Attribute("Include")?.Value);
|
||||
projectReferences.Should().BeEquivalentTo(knownProjectReferences, $"Known project references for Microsoft.NET.Build.Containers project are different from actual. Check if this is expected. If the new project reference is expected, add it to {nameof(knownProjectReferences)} and verify they are included to NuGet package in package.csproj correctly");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PackageContentTest()
|
||||
{
|
||||
string ignoredZipFileEntriesPrefix = "package/services/metadata";
|
||||
|
||||
IReadOnlyList<string> packageContents = new List<string>()
|
||||
{
|
||||
"_rels/.rels",
|
||||
"[Content_Types].xml",
|
||||
"build/Microsoft.NET.Build.Containers.props",
|
||||
"build/Microsoft.NET.Build.Containers.targets",
|
||||
"containerize/containerize.dll",
|
||||
"containerize/containerize.runtimeconfig.json",
|
||||
"containerize/Microsoft.DotNet.Cli.Utils.dll",
|
||||
"containerize/Microsoft.NET.Build.Containers.dll",
|
||||
"containerize/Newtonsoft.Json.dll",
|
||||
"containerize/NuGet.Common.dll",
|
||||
"containerize/NuGet.Configuration.dll",
|
||||
"containerize/NuGet.DependencyResolver.Core.dll",
|
||||
"containerize/NuGet.Frameworks.dll",
|
||||
"containerize/NuGet.LibraryModel.dll",
|
||||
"containerize/NuGet.Packaging.dll",
|
||||
"containerize/NuGet.ProjectModel.dll",
|
||||
"containerize/NuGet.Protocol.dll",
|
||||
"containerize/NuGet.Versioning.dll",
|
||||
"containerize/System.CommandLine.dll",
|
||||
"containerize/Valleysoft.DockerCredsProvider.dll",
|
||||
"Icon.png",
|
||||
"Microsoft.NET.Build.Containers.nuspec",
|
||||
"README.md",
|
||||
"tasks/net472/Microsoft.NET.Build.Containers.dll",
|
||||
"tasks/net472/Newtonsoft.Json.dll",
|
||||
"tasks/net472/NuGet.Common.dll",
|
||||
"tasks/net472/NuGet.Configuration.dll",
|
||||
"tasks/net472/NuGet.DependencyResolver.Core.dll",
|
||||
"tasks/net472/NuGet.Frameworks.dll",
|
||||
"tasks/net472/NuGet.LibraryModel.dll",
|
||||
"tasks/net472/NuGet.Packaging.Core.dll",
|
||||
"tasks/net472/NuGet.Packaging.dll",
|
||||
"tasks/net472/NuGet.ProjectModel.dll",
|
||||
"tasks/net472/NuGet.Protocol.dll",
|
||||
"tasks/net472/NuGet.Versioning.dll",
|
||||
"tasks/net7.0/Microsoft.DotNet.Cli.Utils.dll",
|
||||
"tasks/net7.0/Microsoft.NET.Build.Containers.deps.json",
|
||||
"tasks/net7.0/Microsoft.NET.Build.Containers.dll",
|
||||
"tasks/net7.0/Newtonsoft.Json.dll",
|
||||
"tasks/net7.0/NuGet.Common.dll",
|
||||
"tasks/net7.0/NuGet.Configuration.dll",
|
||||
"tasks/net7.0/NuGet.DependencyResolver.Core.dll",
|
||||
"tasks/net7.0/NuGet.Frameworks.dll",
|
||||
"tasks/net7.0/NuGet.LibraryModel.dll",
|
||||
"tasks/net7.0/NuGet.Packaging.dll",
|
||||
"tasks/net7.0/NuGet.Packaging.Core.dll",
|
||||
"tasks/net7.0/NuGet.ProjectModel.dll",
|
||||
"tasks/net7.0/NuGet.Protocol.dll",
|
||||
"tasks/net7.0/NuGet.Versioning.dll",
|
||||
"tasks/net7.0/Valleysoft.DockerCredsProvider.dll"
|
||||
};
|
||||
|
||||
string packageFilePath = Path.Combine(TestContext.Current.TestExecutionDirectory, "Container", "package", $"Microsoft.NET.Build.Containers.{Product.Version}.nupkg");
|
||||
using ZipArchive archive = new(File.OpenRead(packageFilePath), ZipArchiveMode.Read, false);
|
||||
|
||||
archive.Entries
|
||||
.Select(e => e.FullName)
|
||||
.Where(e => !e.StartsWith(ignoredZipFileEntriesPrefix, StringComparison.InvariantCultureIgnoreCase))
|
||||
.Should()
|
||||
.BeEquivalentTo(packageContents, $"Microsoft.NET.Build.Containers.{Product.Version}.nupkg content differs from expected. Please add the entry to the list, if the addition is expected.");
|
||||
}
|
||||
}
|
|
@ -16,21 +16,21 @@ public class ParseContainerPropertiesTests
|
|||
[DockerAvailableFact]
|
||||
public void Baseline()
|
||||
{
|
||||
var (project, _, d) = ProjectInitializer.InitProject(new () {
|
||||
var (project, logs, d) = ProjectInitializer.InitProject(new () {
|
||||
[ContainerBaseImage] = "mcr.microsoft.com/dotnet/runtime:7.0",
|
||||
[ContainerRegistry] = "localhost:5010",
|
||||
[ContainerImageName] = "dotnet/testimage",
|
||||
[ContainerRepository] = "dotnet/testimage",
|
||||
[ContainerImageTags] = "7.0;latest"
|
||||
});
|
||||
using var _ = d;
|
||||
var instance = project.CreateProjectInstance(global::Microsoft.Build.Execution.ProjectInstanceSettings.None);
|
||||
Assert.True(instance.Build(new[]{ComputeContainerConfig}, null, null, out var outputs));
|
||||
Assert.True(instance.Build(new[]{ComputeContainerConfig}, new [] { logs }, null, out var outputs));
|
||||
|
||||
Assert.Equal("mcr.microsoft.com", instance.GetPropertyValue(ContainerBaseRegistry));
|
||||
Assert.Equal("dotnet/runtime", instance.GetPropertyValue(ContainerBaseName));
|
||||
Assert.Equal("7.0", instance.GetPropertyValue(ContainerBaseTag));
|
||||
|
||||
Assert.Equal("dotnet/testimage", instance.GetPropertyValue(ContainerImageName));
|
||||
Assert.Equal("dotnet/testimage", instance.GetPropertyValue(ContainerRepository));
|
||||
instance.GetItems(ContainerImageTags).Select(i => i.EvaluatedInclude).ToArray().Should().BeEquivalentTo(new[] { "7.0", "latest" });
|
||||
instance.GetItems("ProjectCapability").Select(i => i.EvaluatedInclude).ToArray().Should().BeEquivalentTo(new[] { "NetSdkOCIImageBuild" });
|
||||
}
|
||||
|
@ -38,13 +38,13 @@ public class ParseContainerPropertiesTests
|
|||
[DockerAvailableFact]
|
||||
public void SpacesGetReplacedWithDashes()
|
||||
{
|
||||
var (project, _, d) = ProjectInitializer.InitProject(new () {
|
||||
var (project, logs, d) = ProjectInitializer.InitProject(new () {
|
||||
[ContainerBaseImage] = "mcr.microsoft.com/dotnet runtime:7.0",
|
||||
[ContainerRegistry] = "localhost:5010"
|
||||
});
|
||||
using var _ = d;
|
||||
var instance = project.CreateProjectInstance(global::Microsoft.Build.Execution.ProjectInstanceSettings.None);
|
||||
Assert.True(instance.Build(new[]{ComputeContainerConfig}, null, null, out var outputs));
|
||||
Assert.True(instance.Build(new[]{ComputeContainerConfig}, new [] { logs }, null, out var outputs));
|
||||
|
||||
Assert.Equal("mcr.microsoft.com",instance.GetPropertyValue(ContainerBaseRegistry));
|
||||
Assert.Equal("dotnet-runtime", instance.GetPropertyValue(ContainerBaseName));
|
||||
|
@ -57,13 +57,13 @@ public class ParseContainerPropertiesTests
|
|||
var (project, logs, d) = ProjectInitializer.InitProject(new () {
|
||||
[ContainerBaseImage] = "mcr.microsoft.com/dotnet/runtime:7.0",
|
||||
[ContainerRegistry] = "localhost:5010",
|
||||
[ContainerImageName] = "dotnet testimage",
|
||||
[ContainerRepository] = "dotnet testimage",
|
||||
[ContainerImageTag] = "5.0"
|
||||
});
|
||||
using var _ = d;
|
||||
var instance = project.CreateProjectInstance(global::Microsoft.Build.Execution.ProjectInstanceSettings.None);
|
||||
Assert.True(instance.Build(new[]{ComputeContainerConfig}, new [] { logs }, null, out var outputs));
|
||||
Assert.Contains(logs.Messages, m => m.Message?.Contains("'ContainerImageName' was not a valid container image name, it was normalized to 'dotnet-testimage'") == true);
|
||||
Assert.Contains(logs.Messages, m => m.Message?.Contains("'ContainerRepository' was not a valid container image name, it was normalized to 'dotnet-testimage'") == true);
|
||||
}
|
||||
|
||||
[DockerAvailableFact]
|
||||
|
@ -72,7 +72,7 @@ public class ParseContainerPropertiesTests
|
|||
var (project, logs, d) = ProjectInitializer.InitProject(new () {
|
||||
[ContainerBaseImage] = "mcr.microsoft.com/dotnet/runtime:7.0",
|
||||
[ContainerRegistry] = "localhost:5010",
|
||||
[ContainerImageName] = "dotnet/testimage",
|
||||
[ContainerRepository] = "dotnet/testimage",
|
||||
[ContainerImageTag] = "5 0"
|
||||
});
|
||||
using var _ = d;
|
||||
|
@ -89,7 +89,7 @@ public class ParseContainerPropertiesTests
|
|||
var (project, logs, d) = ProjectInitializer.InitProject(new () {
|
||||
[ContainerBaseImage] = "mcr.microsoft.com/dotnet/runtime:7.0",
|
||||
[ContainerRegistry] = "localhost:5010",
|
||||
[ContainerImageName] = "dotnet/testimage",
|
||||
[ContainerRepository] = "dotnet/testimage",
|
||||
[ContainerImageTag] = "5.0",
|
||||
[ContainerImageTags] = "latest;oldest"
|
||||
});
|
||||
|
|
|
@ -31,6 +31,21 @@ public class TargetsTests
|
|||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanDeferToContainerImageNameWhenPresent() {
|
||||
var customImageName = "my-container-app";
|
||||
var (project, logger, d) = ProjectInitializer.InitProject(new()
|
||||
{
|
||||
[ContainerImageName] = customImageName
|
||||
});
|
||||
using var _ = d;
|
||||
var instance = project.CreateProjectInstance(global::Microsoft.Build.Execution.ProjectInstanceSettings.None);
|
||||
instance.Build(new[] { ComputeContainerConfig }, new []{ logger });
|
||||
logger.Warnings.Should().HaveCount(1, "a warning for the use of the old ContainerImageName property should have been created");
|
||||
logger.Warnings[0].Code.Should().Be(KnownStrings.ErrorCodes.CONTAINER003);
|
||||
Assert.Equal(customImageName, instance.GetPropertyValue(ContainerRepository));
|
||||
}
|
||||
|
||||
[InlineData("WebApplication44", "webapplication44", true)]
|
||||
[InlineData("friendly-suspicious-alligator", "friendly-suspicious-alligator", true)]
|
||||
[InlineData("*friendly-suspicious-alligator", "", false)]
|
||||
|
@ -39,14 +54,14 @@ public class TargetsTests
|
|||
[Theory]
|
||||
public void CanNormalizeInputContainerNames(string projectName, string expectedContainerImageName, bool shouldPass)
|
||||
{
|
||||
var (project, _, d) = ProjectInitializer.InitProject(new()
|
||||
var (project, logger, d) = ProjectInitializer.InitProject(new()
|
||||
{
|
||||
[AssemblyName] = projectName
|
||||
}, projectName: $"{nameof(CanNormalizeInputContainerNames)}_{projectName}_{expectedContainerImageName}_{shouldPass}");
|
||||
using var _ = d;
|
||||
var instance = project.CreateProjectInstance(global::Microsoft.Build.Execution.ProjectInstanceSettings.None);
|
||||
instance.Build(new[] { ComputeContainerConfig }, null, null, out var outputs).Should().Be(shouldPass, "Build should have succeeded");
|
||||
Assert.Equal(expectedContainerImageName, instance.GetPropertyValue(ContainerImageName));
|
||||
instance.Build(new[] { ComputeContainerConfig }, new [] { logger }, null, out var outputs).Should().Be(shouldPass, "Build should have succeeded");
|
||||
Assert.Equal(expectedContainerImageName, instance.GetPropertyValue(ContainerRepository));
|
||||
}
|
||||
|
||||
[InlineData("7.0.100", true)]
|
||||
|
@ -58,16 +73,25 @@ public class TargetsTests
|
|||
[Theory]
|
||||
public void CanWarnOnInvalidSDKVersions(string sdkVersion, bool isAllowed)
|
||||
{
|
||||
var (project, _, d) = ProjectInitializer.InitProject(new()
|
||||
var (project, logger, d) = ProjectInitializer.InitProject(new()
|
||||
{
|
||||
["NETCoreSdkVersion"] = sdkVersion,
|
||||
["PublishProfile"] = "DefaultContainer"
|
||||
}, projectName: $"{nameof(CanWarnOnInvalidSDKVersions)}_{sdkVersion}_{isAllowed}");
|
||||
using var _ = d;
|
||||
var instance = project.CreateProjectInstance(global::Microsoft.Build.Execution.ProjectInstanceSettings.None);
|
||||
instance.Build(new[]{"_ContainerVerifySDKVersion"}, new[] { logger }, null, out var outputs).Should().Be(isAllowed);
|
||||
var derivedIsAllowed = Boolean.Parse(project.GetProperty("_IsSDKContainerAllowedVersion").EvaluatedValue);
|
||||
// var buildResult = instance.Build(new[]{"_ContainerVerifySDKVersion"}, null, null, out var outputs);
|
||||
derivedIsAllowed.Should().Be(isAllowed, $"SDK version {(isAllowed ? "should" : "should not")} have been allowed ");
|
||||
if (isAllowed)
|
||||
{
|
||||
logger.Errors.Should().HaveCount(0, "an error should not have been created");
|
||||
derivedIsAllowed.Should().Be(true, "SDK version {0} should have been allowed", sdkVersion);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Errors.Should().HaveCount(1, "an error should have been created").And.Satisfy(error => error.Code == KnownStrings.ErrorCodes.CONTAINER002);
|
||||
derivedIsAllowed.Should().Be(false, "SDK version {0} should not have been allowed", sdkVersion);
|
||||
}
|
||||
}
|
||||
|
||||
[InlineData(true)]
|
||||
|
@ -75,13 +99,13 @@ public class TargetsTests
|
|||
[Theory]
|
||||
public void GetsConventionalLabelsByDefault(bool shouldEvaluateLabels)
|
||||
{
|
||||
var (project, _, d) = ProjectInitializer.InitProject(new()
|
||||
var (project, logger, d) = ProjectInitializer.InitProject(new()
|
||||
{
|
||||
[ContainerGenerateLabels] = shouldEvaluateLabels.ToString()
|
||||
}, projectName: $"{nameof(GetsConventionalLabelsByDefault)}_{shouldEvaluateLabels}");
|
||||
using var _ = d;
|
||||
var instance = project.CreateProjectInstance(global::Microsoft.Build.Execution.ProjectInstanceSettings.None);
|
||||
instance.Build(new[] { ComputeContainerConfig }, null, null, out var outputs).Should().BeTrue("Build should have succeeded");
|
||||
instance.Build(new[] { ComputeContainerConfig }, new [] { logger }, null, out var outputs).Should().BeTrue("Build should have succeeded");
|
||||
if (shouldEvaluateLabels)
|
||||
{
|
||||
instance.GetItems(ContainerLabel).Should().NotBeEmpty("Should have evaluated some labels by default");
|
||||
|
@ -110,7 +134,7 @@ public class TargetsTests
|
|||
}, projectName: $"{nameof(ShouldNotIncludeSourceControlLabelsUnlessUserOptsIn)}_{includeSourceControl}");
|
||||
using var _ = d;
|
||||
var instance = project.CreateProjectInstance(global::Microsoft.Build.Execution.ProjectInstanceSettings.None);
|
||||
instance.Build(new[] { ComputeContainerConfig }, null, null, out var outputs).Should().BeTrue("Build should have succeeded but failed due to {0}", String.Join("\n", logger.AllMessages));
|
||||
instance.Build(new[] { ComputeContainerConfig }, new [] { logger }, null, out var outputs).Should().BeTrue("Build should have succeeded but failed due to {0}", String.Join("\n", logger.AllMessages));
|
||||
var labels = instance.GetItems(ContainerLabel);
|
||||
if (includeSourceControl)
|
||||
{
|
||||
|
@ -156,7 +180,7 @@ public class TargetsTests
|
|||
}, projectName: $"{nameof(CanComputeTagsForSupportedSDKVersions)}_{sdkVersion}_{tfm}_{expectedTag}");
|
||||
using var _ = d;
|
||||
var instance = project.CreateProjectInstance(global::Microsoft.Build.Execution.ProjectInstanceSettings.None);
|
||||
instance.Build(new[]{"_ComputeContainerBaseImageTag"}, null, null, out var outputs).Should().BeTrue(String.Join(Environment.NewLine, logger.Errors));
|
||||
instance.Build(new[]{"_ComputeContainerBaseImageTag"}, new [] { logger }, null, out var outputs).Should().BeTrue(String.Join(Environment.NewLine, logger.Errors));
|
||||
var computedTag = instance.GetProperty("_ContainerBaseImageTag").EvaluatedValue;
|
||||
computedTag.Should().Be(expectedTag);
|
||||
}
|
||||
|
@ -176,10 +200,10 @@ public class TargetsTests
|
|||
["TargetFrameworkVersion"] = tfm,
|
||||
["TargetFramework"] = "net" + tfm.TrimStart('v'),
|
||||
["ContainerRuntimeIdentifier"] = rid
|
||||
}, projectName: $"{nameof(CanComputeTagsForSupportedSDKVersions)}_{tfm}_{rid}_{expectedUser}");
|
||||
}, projectName: $"{nameof(CanComputeContainerUser)}_{tfm}_{rid}_{expectedUser}");
|
||||
using var _ = d;
|
||||
var instance = project.CreateProjectInstance(global::Microsoft.Build.Execution.ProjectInstanceSettings.None);
|
||||
instance.Build(new[]{ComputeContainerConfig}, null, null, out var outputs).Should().BeTrue(String.Join(Environment.NewLine, logger.Errors));
|
||||
instance.Build(new[]{ComputeContainerConfig}, new [] { logger }, null, out var outputs).Should().BeTrue(String.Join(Environment.NewLine, logger.Errors));
|
||||
var computedTag = instance.GetProperty("ContainerUser")?.EvaluatedValue;
|
||||
computedTag.Should().Be(expectedUser);
|
||||
}
|
||||
|
|
|
@ -167,6 +167,241 @@ namespace ManifestReaderTests
|
|||
"ios: 18.0.1/7.0.400");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ItUsesManifestsFromWorkloadSet()
|
||||
{
|
||||
Initialize("8.0.200");
|
||||
|
||||
CreateMockManifest(_manifestRoot, "8.0.100", "ios", "11.0.1", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.100", "ios", "11.0.2", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.200", "ios", "12.0.1", true);
|
||||
|
||||
CreateMockManifest(_manifestRoot, "8.0.200", "android", "33.0.1", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.200", "android", "33.0.2-rc.1", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.200", "android", "33.0.2", true);
|
||||
|
||||
CreateMockManifest(_manifestRoot, "8.0.200-rc.1", "maui", "15.0.1-preview.123", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.200-rc.2", "maui", "15.0.1-rc.456", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.200", "maui", "15.0.1", true);
|
||||
|
||||
|
||||
CreateMockWorkloadSet(_manifestRoot, "8.0.200", "8.0.200", """
|
||||
{
|
||||
"ios": "11.0.2/8.0.100",
|
||||
"android": "33.0.2-rc.1/8.0.200",
|
||||
"maui": "15.0.1-rc.456/8.0.200-rc.2"
|
||||
}
|
||||
""");
|
||||
|
||||
var sdkDirectoryWorkloadManifestProvider
|
||||
= new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null);
|
||||
|
||||
GetManifestContents(sdkDirectoryWorkloadManifestProvider)
|
||||
.Should()
|
||||
.BeEquivalentTo("ios: 11.0.2/8.0.100", "android: 33.0.2-rc.1/8.0.200", "maui: 15.0.1-rc.456/8.0.200-rc.2");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ItUsesLatestWorkloadSet()
|
||||
{
|
||||
Initialize("8.0.200");
|
||||
|
||||
CreateMockManifest(_manifestRoot, "8.0.100", "ios", "11.0.1", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.100", "ios", "11.0.2", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.200", "ios", "12.0.1", true);
|
||||
|
||||
CreateMockWorkloadSet(_manifestRoot, "8.0.200", "8.0.201", """
|
||||
{
|
||||
"ios": "11.0.2/8.0.100"
|
||||
}
|
||||
""");
|
||||
|
||||
CreateMockWorkloadSet(_manifestRoot, "8.0.200", "8.0.202", """
|
||||
{
|
||||
"ios": "12.0.1/8.0.200"
|
||||
}
|
||||
""");
|
||||
|
||||
var sdkDirectoryWorkloadManifestProvider
|
||||
= new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null);
|
||||
|
||||
GetManifestContents(sdkDirectoryWorkloadManifestProvider)
|
||||
.Should()
|
||||
.BeEquivalentTo("ios: 12.0.1/8.0.200");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ItUsesLatestManifestThatIsNotInWorkloadSet()
|
||||
{
|
||||
Initialize("8.0.200");
|
||||
|
||||
CreateMockManifest(_manifestRoot, "8.0.100", "ios", "11.0.1", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.100", "ios", "11.0.2", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.200", "ios", "12.0.1", true);
|
||||
|
||||
CreateMockManifest(_manifestRoot, "8.0.200", "android", "33.0.1", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.200", "android", "33.0.2-rc.1", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.200", "android", "33.0.2", true);
|
||||
|
||||
CreateMockManifest(_manifestRoot, "8.0.200-rc.1", "maui", "15.0.1-preview.123", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.200-rc.2", "maui", "15.0.1-rc.456", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.200", "maui", "15.0.1", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.200", "maui", "15.0.2", true);
|
||||
|
||||
CreateMockWorkloadSet(_manifestRoot, "8.0.200", "8.0.200", """
|
||||
{
|
||||
"ios": "11.0.2/8.0.100",
|
||||
"android": "33.0.2-rc.1/8.0.200"
|
||||
}
|
||||
""");
|
||||
|
||||
var sdkDirectoryWorkloadManifestProvider
|
||||
= new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null);
|
||||
|
||||
GetManifestContents(sdkDirectoryWorkloadManifestProvider)
|
||||
.Should()
|
||||
.BeEquivalentTo("ios: 11.0.2/8.0.100", "android: 33.0.2-rc.1/8.0.200", "maui: 15.0.2/8.0.200");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ItFallsBackForManifestNotInWorkloadSet()
|
||||
{
|
||||
Initialize("8.0.200");
|
||||
|
||||
var knownWorkloadsFilePath = Path.Combine(_fakeDotnetRootDirectory, "sdk", "8.0.201", "IncludedWorkloadManifests.txt");
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(knownWorkloadsFilePath)!);
|
||||
File.WriteAllText(knownWorkloadsFilePath, "android\nios\nmaui");
|
||||
|
||||
CreateMockManifest(_manifestRoot, "8.0.100", "ios", "11.0.1", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.100", "ios", "11.0.2", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.200", "ios", "12.0.1", true);
|
||||
|
||||
CreateMockManifest(_manifestRoot, "8.0.100", "android", "33.0.1", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.100", "android", "33.0.2-rc.1", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.100", "android", "33.0.2", true);
|
||||
|
||||
CreateMockManifest(_manifestRoot, "8.0.200-rc.1", "maui", "15.0.1-preview.123", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.200-rc.2", "maui", "15.0.1-rc.456", true);
|
||||
|
||||
CreateMockWorkloadSet(_manifestRoot, "8.0.200", "8.0.201", """
|
||||
{
|
||||
"ios": "11.0.2/8.0.100"
|
||||
}
|
||||
""");
|
||||
|
||||
var sdkDirectoryWorkloadManifestProvider
|
||||
= new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.201", userProfileDir: null);
|
||||
|
||||
GetManifestContents(sdkDirectoryWorkloadManifestProvider)
|
||||
.Should()
|
||||
.BeEquivalentTo("ios: 11.0.2/8.0.100", "android: 33.0.2/8.0.100", "maui: 15.0.1-rc.456/8.0.200-rc.2");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ItThrowsIfWorkloadSetHasInvalidVersion()
|
||||
{
|
||||
Initialize("8.0.200");
|
||||
|
||||
CreateMockManifest(_manifestRoot, "8.0.100", "ios", "11.0.1", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.100", "ios", "11.0.2", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.200", "ios", "12.0.1", true);
|
||||
|
||||
CreateMockWorkloadSet(_manifestRoot, "8.0.200", "8.0.200.1", """
|
||||
{
|
||||
"ios": "11.0.2/8.0.100"
|
||||
}
|
||||
""");
|
||||
|
||||
Assert.Throws<FormatException>(() => new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ItThrowsIfManifestFromWorkloadSetIsNotFound()
|
||||
{
|
||||
Initialize("8.0.200");
|
||||
|
||||
CreateMockManifest(_manifestRoot, "8.0.100", "ios", "11.0.1", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.100", "ios", "11.0.2", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.200", "ios", "12.0.1", true);
|
||||
|
||||
CreateMockWorkloadSet(_manifestRoot, "8.0.200", "8.0.200", """
|
||||
{
|
||||
"ios": "12.0.2/8.0.200"
|
||||
}
|
||||
""");
|
||||
var sdkDirectoryWorkloadManifestProvider
|
||||
= new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null);
|
||||
|
||||
Assert.Throws<FileNotFoundException>(() => GetManifestContents(sdkDirectoryWorkloadManifestProvider).ToList());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WorkloadSetCanIncludeMultipleJsonFiles()
|
||||
{
|
||||
Initialize("8.0.200");
|
||||
|
||||
CreateMockManifest(_manifestRoot, "8.0.100", "ios", "11.0.1", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.100", "ios", "11.0.2", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.200", "ios", "12.0.1", true);
|
||||
|
||||
CreateMockManifest(_manifestRoot, "8.0.200", "android", "33.0.1", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.200", "android", "33.0.2-rc.1", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.200", "android", "33.0.2", true);
|
||||
|
||||
|
||||
var workloadSetDirectory = Path.Combine(_manifestRoot, "8.0.200", "workloadsets", "8.0.200");
|
||||
Directory.CreateDirectory(workloadSetDirectory);
|
||||
File.WriteAllText(Path.Combine(workloadSetDirectory, "1.workloadset.json"), """
|
||||
{
|
||||
"ios": "11.0.2/8.0.100"
|
||||
}
|
||||
""");
|
||||
File.WriteAllText(Path.Combine(workloadSetDirectory, "2.workloadset.json"), """
|
||||
{
|
||||
"android": "33.0.2-rc.1/8.0.200"
|
||||
}
|
||||
""");
|
||||
|
||||
var sdkDirectoryWorkloadManifestProvider
|
||||
= new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null);
|
||||
|
||||
GetManifestContents(sdkDirectoryWorkloadManifestProvider)
|
||||
.Should()
|
||||
.BeEquivalentTo("ios: 11.0.2/8.0.100", "android: 33.0.2-rc.1/8.0.200");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ItThrowsExceptionIfWorkloadSetJsonFilesHaveDuplicateManifests()
|
||||
{
|
||||
Initialize("8.0.200");
|
||||
|
||||
CreateMockManifest(_manifestRoot, "8.0.100", "ios", "11.0.1", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.100", "ios", "11.0.2", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.200", "ios", "12.0.1", true);
|
||||
|
||||
CreateMockManifest(_manifestRoot, "8.0.200", "android", "33.0.1", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.200", "android", "33.0.2-rc.1", true);
|
||||
CreateMockManifest(_manifestRoot, "8.0.200", "android", "33.0.2", true);
|
||||
|
||||
|
||||
var workloadSetDirectory = Path.Combine(_manifestRoot, "8.0.200", "workloadsets", "8.0.200");
|
||||
Directory.CreateDirectory(workloadSetDirectory);
|
||||
File.WriteAllText(Path.Combine(workloadSetDirectory, "1.workloadset.json"), """
|
||||
{
|
||||
"ios": "11.0.2/8.0.100"
|
||||
}
|
||||
""");
|
||||
File.WriteAllText(Path.Combine(workloadSetDirectory, "2.workloadset.json"), """
|
||||
{
|
||||
"android": "33.0.2-rc.1/8.0.200",
|
||||
"ios": "11.0.2/8.0.100"
|
||||
}
|
||||
""");
|
||||
|
||||
Assert.Throws<ArgumentException>(() =>
|
||||
new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ItShouldReturnManifestsFromTestHook()
|
||||
{
|
||||
|
@ -456,6 +691,16 @@ Microsoft.Net.Workload.Emscripten.net7"
|
|||
File.WriteAllText(Path.Combine(manifestDirectory, "WorkloadManifest.json"), $"{manifestId}: {manifestVersion}/{featureBand}");
|
||||
}
|
||||
|
||||
private void CreateMockWorkloadSet(string manifestRoot, string featureBand, string workloadSetVersion, string workloadSetContents)
|
||||
{
|
||||
var workloadSetDirectory = Path.Combine(manifestRoot, featureBand, "workloadsets", workloadSetVersion);
|
||||
if (!Directory.Exists(workloadSetDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(workloadSetDirectory);
|
||||
}
|
||||
File.WriteAllText(Path.Combine(workloadSetDirectory, "workloadset.workloadset.json"), workloadSetContents);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ItShouldIgnoreManifestsNotFoundInFallback()
|
||||
{
|
||||
|
|
|
@ -22,7 +22,7 @@ public class ParserTests
|
|||
"MyBaseRegistry",
|
||||
command.BaseImageNameOption.Aliases.First(),
|
||||
"MyBaseImageName",
|
||||
command.ImageNameOption.Aliases.First(),
|
||||
command.RepositoryOption.Aliases.First(),
|
||||
"MyImageName",
|
||||
command.WorkingDirectoryOption.Aliases.First(),
|
||||
"MyWorkingDirectory",
|
||||
|
@ -65,7 +65,7 @@ public class ParserTests
|
|||
"MyBaseRegistry",
|
||||
command.BaseImageNameOption.Aliases.First(),
|
||||
"MyBaseImageName",
|
||||
command.ImageNameOption.Aliases.First(),
|
||||
command.RepositoryOption.Aliases.First(),
|
||||
"MyImageName",
|
||||
command.WorkingDirectoryOption.Aliases.First(),
|
||||
"MyWorkingDirectory",
|
||||
|
@ -101,7 +101,7 @@ public class ParserTests
|
|||
"MyBaseRegistry",
|
||||
command.BaseImageNameOption.Aliases.First(),
|
||||
"MyBaseImageName",
|
||||
command.ImageNameOption.Aliases.First(),
|
||||
command.RepositoryOption.Aliases.First(),
|
||||
"MyImageName",
|
||||
command.WorkingDirectoryOption.Aliases.First(),
|
||||
"MyWorkingDirectory",
|
||||
|
@ -133,7 +133,7 @@ public class ParserTests
|
|||
"MyBaseRegistry",
|
||||
command.BaseImageNameOption.Aliases.First(),
|
||||
"MyBaseImageName",
|
||||
command.ImageNameOption.Aliases.First(),
|
||||
command.RepositoryOption.Aliases.First(),
|
||||
"MyImageName",
|
||||
command.WorkingDirectoryOption.Aliases.First(),
|
||||
"MyWorkingDirectory",
|
||||
|
@ -177,7 +177,7 @@ public class ParserTests
|
|||
"MyBaseRegistry",
|
||||
command.BaseImageNameOption.Aliases.First(),
|
||||
"MyBaseImageName",
|
||||
command.ImageNameOption.Aliases.First(),
|
||||
command.RepositoryOption.Aliases.First(),
|
||||
"MyImageName",
|
||||
command.WorkingDirectoryOption.Aliases.First(),
|
||||
"MyWorkingDirectory",
|
||||
|
@ -222,7 +222,7 @@ public class ParserTests
|
|||
"MyBaseRegistry",
|
||||
command.BaseImageNameOption.Aliases.First(),
|
||||
"MyBaseImageName",
|
||||
command.ImageNameOption.Aliases.First(),
|
||||
command.RepositoryOption.Aliases.First(),
|
||||
"MyImageName",
|
||||
command.WorkingDirectoryOption.Aliases.First(),
|
||||
"MyWorkingDirectory",
|
||||
|
|
|
@ -340,7 +340,7 @@ namespace Microsoft.DotNet.Cli.Workload.Update.Tests
|
|||
|
||||
updateCommand.Execute();
|
||||
_reporter.Lines.Count().Should().Be(3);
|
||||
string.Join("", _reporter.Lines).Should().Contain("SampleManifest");
|
||||
string.Join("", _reporter.Lines).Should().Contain("samplemanifest");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
@ -454,7 +454,13 @@ namespace Microsoft.DotNet.Cli.Workload.Update.Tests
|
|||
var installer = includeInstalledPacks ?
|
||||
new MockPackWorkloadInstaller(failingWorkload, failingPack, installedWorkloads: installedWorkloads, installedPacks: installedPacks) :
|
||||
new MockPackWorkloadInstaller(failingWorkload, failingPack, installedWorkloads: installedWorkloads);
|
||||
var workloadResolver = WorkloadResolver.CreateForTests(new MockManifestProvider(new[] { _manifestPath }), dotnetRoot);
|
||||
|
||||
var copiedManifestFolder = Path.Combine(dotnetRoot, "sdk-manifests", new SdkFeatureBand(sdkVersion).ToString(), "SampleManifest");
|
||||
Directory.CreateDirectory(copiedManifestFolder);
|
||||
var copiedManifestFile = Path.Combine(copiedManifestFolder, "WorkloadManifest.json");
|
||||
File.Copy(_manifestPath, copiedManifestFile);
|
||||
|
||||
var workloadResolver = WorkloadResolver.CreateForTests(new MockManifestProvider(new[] { copiedManifestFile }), dotnetRoot);
|
||||
installer.WorkloadResolver = workloadResolver;
|
||||
var nugetDownloader = new MockNuGetPackageDownloader(dotnetRoot);
|
||||
var manifestUpdater = new MockWorkloadManifestUpdater(manifestUpdates, _manifestPath);
|
||||
|
|
Загрузка…
Ссылка в новой задаче