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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions src/windows/wslc/tasks/ImageTasks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,16 @@ namespace {
// Builds the representation of an image, shared by the table and json output so the two cannot
// drift. Every value is emitted as a string, "<none>" is used for missing repository/tag data,
// and the id is truncated unless --no-trunc is passed, in which case it keeps the algorithm prefix.
ImageOutputInformation ToImageOutput(const ImageInformation& image, bool truncate)
// CreatedSince is the only field that varies with the format: docker renders it in invariant
// English, so json keeps that while the table is localized.
ImageOutputInformation ToImageOutput(const ImageInformation& image, bool truncate, FormatType format)
{
ImageOutputInformation entry;
entry.Containers = image.Containers < 0 ? std::string{c_imageNotAvailable} : std::to_string(image.Containers);

entry.CreatedAt = EpochToLocalDisplayTime(image.Created);
entry.CreatedSince = WideToMultiByte(FormatRelativeTime(image.Created));
entry.CreatedSince =
WideToMultiByte(format == FormatType::Json ? FormatInvariantRelativeTime(image.Created) : FormatRelativeTime(image.Created));
entry.Digest = c_none;
entry.ID = truncate ? TruncateId(image.Id, true) : image.Id;
entry.Repository = image.Repository.value_or(std::string{c_none});
Expand Down Expand Up @@ -214,7 +217,7 @@ void ListImages(CLIExecutionContext& context)
{
for (const auto& image : images)
{
context.Terminal.Output(L"{}\n", ToJsonW(ToImageOutput(image, trunc), c_jsonCompactIndent));
context.Terminal.Output(L"{}\n", ToJsonW(ToImageOutput(image, trunc, format), c_jsonCompactIndent));
}

break;
Expand All @@ -239,7 +242,7 @@ void ListImages(CLIExecutionContext& context)

for (const auto& image : images)
{
const auto entry = ToImageOutput(image, trunc);
const auto entry = ToImageOutput(image, trunc, format);
table.WriteRow({
MultiByteToWide(entry.Repository),
MultiByteToWide(entry.Tag),
Expand Down
4 changes: 2 additions & 2 deletions test/windows/wslc/e2e/WSLCE2EImageListTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ class WSLCE2EImageListTests
{
// The table and json output must report the same values, formatted the way docker formats
// them: SI sizes ("120MB", not "119.86 MB") and "<none>" for missing repository/tag data.
// CREATED is excluded because the table localizes it while json does not.
const auto jsonResult = RunWslc(L"image list --format json");
jsonResult.Verify({.Stderr = L"", .ExitCode = 0});

Expand All @@ -288,8 +289,7 @@ class WSLCE2EImageListTests
return line.find(wsl::shared::string::MultiByteToWide(image.ID)) != std::wstring::npos &&
line.find(wsl::shared::string::MultiByteToWide(image.Repository)) != std::wstring::npos &&
line.find(wsl::shared::string::MultiByteToWide(image.Tag)) != std::wstring::npos &&
line.find(wsl::shared::string::MultiByteToWide(image.Size)) != std::wstring::npos &&
line.find(wsl::shared::string::MultiByteToWide(image.CreatedSince)) != std::wstring::npos;
line.find(wsl::shared::string::MultiByteToWide(image.Size)) != std::wstring::npos;
Comment thread
ggarzia-MSFT marked this conversation as resolved.
Resolved
});

VERIFY_IS_TRUE(found, std::format(L"Table output has no row matching json values: {}", row).c_str());
Expand Down