Skip to content

Commit f33b402

Browse files
authored
Shorter default installer log filename (#5705)
## Change Make `OutputTimePoint` more flexible by allowing arbitrary fields and behaviors to be requested via flags. Shorten the default installer log filename by removing the leading `WinGet-` and dropping the milliseconds. Some installers use the log file path as a base with no error handling to ensure a valid path is produced. Anything we can remove means more likely success.
1 parent 4c85f5b commit f33b402

File tree

5 files changed

+129
-39
lines changed

5 files changed

+129
-39
lines changed

src/AppInstallerCLICore/Workflows/ShellExecuteInstallerHandler.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,11 +173,9 @@ namespace AppInstaller::CLI::Workflow
173173
const auto& manifest = context.Get<Execution::Data::Manifest>();
174174

175175
auto path = Runtime::GetPathTo(Runtime::PathName::DefaultLogLocation);
176-
path /= Logging::FileLogger::DefaultPrefix();
176+
path /= Utility::ConvertToUTF16(manifest.Id + '.' + manifest.Version);
177177
path += '-';
178-
path += Utility::ConvertToUTF16(manifest.Id + '.' + manifest.Version);
179-
path += '-';
180-
path += Utility::GetCurrentTimeForFilename();
178+
path += Utility::GetCurrentTimeForFilename(true);
181179
path += Logging::FileLogger::DefaultExt();
182180

183181
logPath = path.u8string();

src/AppInstallerCLITests/DateTime.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,12 @@ TEST_CASE("GetTimePointFromVersion", "[datetime]")
8282
system_clock::time_point now = system_clock::now();
8383
REQUIRE(GetTimePointFromVersion(UInt64Version{ StringFromTimePoint(now) }) == time_point_cast<minutes>(now));
8484
}
85+
86+
TEST_CASE("ShortFileTime", "[datetime]")
87+
{
88+
auto shortTime = GetCurrentTimeForFilename(true);
89+
auto longTime = GetCurrentTimeForFilename(false);
90+
INFO(shortTime);
91+
INFO(longTime);
92+
REQUIRE(shortTime.length() < longTime.length());
93+
}

src/AppInstallerSharedLib/DateTime.cpp

Lines changed: 89 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,93 @@
33
#include "pch.h"
44
#include "Public/AppInstallerDateTime.h"
55

6+
using namespace std::chrono;
7+
68
namespace AppInstaller::Utility
79
{
8-
// If moved to C++20, this can be replaced with standard library implementations.
9-
void OutputTimePoint(std::ostream& stream, const std::chrono::system_clock::time_point& time, bool useRFC3339)
10+
namespace
1011
{
11-
using namespace std::chrono;
12-
13-
tm localTime{};
14-
auto tt = system_clock::to_time_t(time);
15-
_localtime64_s(&localTime, &tt);
16-
17-
stream
18-
<< std::setw(4) << (1900 + localTime.tm_year) << '-'
19-
<< std::setw(2) << std::setfill('0') << (1 + localTime.tm_mon) << '-'
20-
<< std::setw(2) << std::setfill('0') << localTime.tm_mday << (useRFC3339 ? 'T' : ' ')
21-
<< std::setw(2) << std::setfill('0') << localTime.tm_hour << ':'
22-
<< std::setw(2) << std::setfill('0') << localTime.tm_min << ':'
23-
<< std::setw(2) << std::setfill('0') << localTime.tm_sec << '.';
24-
25-
// Get partial seconds
26-
auto sinceEpoch = time.time_since_epoch();
27-
auto leftoverMillis = duration_cast<milliseconds>(sinceEpoch) - duration_cast<seconds>(sinceEpoch);
12+
struct OutputTimePointContext
13+
{
14+
OutputTimePointContext(std::ostream& stream, const std::chrono::system_clock::time_point& time, TimeFacet facet) :
15+
Stream(stream), Time(time), Facet(facet)
16+
{
17+
auto tt = system_clock::to_time_t(time);
18+
_localtime64_s(&LocalTime, &tt);
19+
}
20+
21+
std::ostream& Stream;
22+
const std::chrono::system_clock::time_point& Time;
23+
tm LocalTime{};
24+
TimeFacet Facet;
25+
};
26+
27+
struct OutputTimePointFacetInfo
28+
{
29+
TimeFacet Facet;
30+
char FollowingSeparator;
31+
void (*Action)(const OutputTimePointContext&);
32+
};
33+
}
2834

29-
stream << std::setw(3) << std::setfill('0') << leftoverMillis.count();
35+
void OutputTimePoint(std::ostream& stream, const std::chrono::system_clock::time_point& time, bool useRFC3339)
36+
{
37+
OutputTimePoint(stream, time, TimeFacet::Default | (useRFC3339 ? TimeFacet::RFC3339 : TimeFacet::None));
38+
}
3039

31-
if (useRFC3339)
40+
// If moved to C++20, this can be replaced with standard library implementations.
41+
void OutputTimePoint(std::ostream& stream, const std::chrono::system_clock::time_point& time, TimeFacet facet)
42+
{
43+
OutputTimePointContext context{ stream, time, facet };
44+
using Ctx = const OutputTimePointContext&;
45+
46+
bool useRFC3339 = WI_IsFlagSet(facet, TimeFacet::RFC3339);
47+
bool filename = WI_IsFlagSet(facet, TimeFacet::Filename);
48+
char day_time_separator = useRFC3339 ? 'T' : (filename ? '-' : ' ');
49+
char time_field_separator = filename ? '-' : ':';
50+
51+
bool needsSeparator = false;
52+
char currentSeparator = '-';
53+
54+
for (const auto& info : {
55+
OutputTimePointFacetInfo{ TimeFacet::ShortYear, '-', [](Ctx ctx) { ctx.Stream << (ctx.LocalTime.tm_year - 100); }},
56+
OutputTimePointFacetInfo{ TimeFacet::Year, '-', [](Ctx ctx) { ctx.Stream << (1900 + ctx.LocalTime.tm_year); }},
57+
OutputTimePointFacetInfo{ TimeFacet::Month, '-', [](Ctx ctx) { ctx.Stream << std::setw(2) << std::setfill('0') << (1 + ctx.LocalTime.tm_mon); }},
58+
OutputTimePointFacetInfo{ TimeFacet::Day, day_time_separator, [](Ctx ctx) { ctx.Stream << std::setw(2) << std::setfill('0') << ctx.LocalTime.tm_mday; }},
59+
OutputTimePointFacetInfo{ TimeFacet::Hour, time_field_separator, [](Ctx ctx) { ctx.Stream << std::setw(2) << std::setfill('0') << ctx.LocalTime.tm_hour; }},
60+
OutputTimePointFacetInfo{ TimeFacet::Minute, time_field_separator, [](Ctx ctx) { ctx.Stream << std::setw(2) << std::setfill('0') << ctx.LocalTime.tm_min; }},
61+
OutputTimePointFacetInfo{ TimeFacet::Second, '.', [](Ctx ctx) { ctx.Stream << std::setw(2) << std::setfill('0') << ctx.LocalTime.tm_sec; }},
62+
OutputTimePointFacetInfo{ TimeFacet::Millisecond, '-', [](Ctx ctx)
63+
{
64+
// Get partial seconds
65+
auto sinceEpoch = ctx.Time.time_since_epoch();
66+
auto leftoverMillis = duration_cast<milliseconds>(sinceEpoch) - duration_cast<seconds>(sinceEpoch);
67+
68+
ctx.Stream << std::setw(3) << std::setfill('0') << leftoverMillis.count();
69+
}},
70+
OutputTimePointFacetInfo{ TimeFacet::RFC3339, '\0', [](Ctx ctx)
71+
{
72+
// RFC 3339 requires adding time zone info.
73+
// No need to bother getting the actual time zone as we don't need it.
74+
// -00:00 represents an unspecified time zone, not UTC.
75+
ctx.Stream << "00:00";
76+
}},
77+
})
3278
{
33-
// RFC 3339 requires adding time zone info.
34-
// No need to bother getting the actual time zone as we don't need it.
35-
// -00:00 represents an unspecified time zone, not UTC.
36-
stream << "-00:00";
79+
if (WI_AreAllFlagsSet(facet, info.Facet))
80+
{
81+
if (needsSeparator)
82+
{
83+
stream << currentSeparator;
84+
}
85+
86+
info.Action(context);
87+
needsSeparator = true;
88+
}
89+
90+
// Getting this right for every mix of facets is probably not possible.
91+
// Future needs can dictate changes here.
92+
currentSeparator = info.FollowingSeparator;
3793
}
3894
}
3995

@@ -44,16 +100,16 @@ namespace AppInstaller::Utility
44100
return std::move(stream).str();
45101
}
46102

47-
std::string GetCurrentTimeForFilename()
103+
std::string TimePointToString(const std::chrono::system_clock::time_point& time, TimeFacet facet)
48104
{
49-
std::stringstream stream;
50-
OutputTimePoint(stream, std::chrono::system_clock::now());
51-
52-
auto result = stream.str();
53-
std::replace(result.begin(), result.end(), ':', '-');
54-
std::replace(result.begin(), result.end(), ' ', '-');
105+
std::ostringstream stream;
106+
OutputTimePoint(stream, time, facet);
107+
return std::move(stream).str();
108+
}
55109

56-
return result;
110+
std::string GetCurrentTimeForFilename(bool shortTime)
111+
{
112+
return TimePointToString(std::chrono::system_clock::now(), (shortTime ? TimeFacet::ShortYearSecondPrecision : TimeFacet::Default) | TimeFacet::Filename);
57113
}
58114

59115
std::string GetCurrentDateForARP()

src/AppInstallerSharedLib/Public/AppInstallerDateTime.h

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,43 @@
77

88
namespace AppInstaller::Utility
99
{
10+
// The individual aspects of a time point.
11+
enum class TimeFacet
12+
{
13+
None = 0x000,
14+
Millisecond = 0x001,
15+
Second = 0x002,
16+
Minute = 0x004,
17+
Hour = 0x008,
18+
Day = 0x010,
19+
Month = 0x020,
20+
Year = 0x040,
21+
// `Year - 2000` [2 digits for 75 more years]
22+
ShortYear = 0x080,
23+
// Includes unspecified time zone
24+
RFC3339 = 0x100,
25+
// Limits special character use
26+
Filename = 0x200,
27+
28+
Default = Year | Month | Day | Hour | Minute | Second | Millisecond,
29+
ShortYearSecondPrecision = ShortYear | Month | Day | Hour | Minute | Second,
30+
};
31+
32+
DEFINE_ENUM_FLAG_OPERATORS(TimeFacet);
33+
1034
// Writes the given time to the given stream.
1135
// Assumes that system_clock uses Linux epoch (as required by C++20 standard).
1236
// Time is also assumed to be after the epoch.
1337
void OutputTimePoint(std::ostream& stream, const std::chrono::system_clock::time_point& time, bool useRFC3339 = false);
38+
void OutputTimePoint(std::ostream& stream, const std::chrono::system_clock::time_point& time, TimeFacet facet);
1439

1540
// Converts the time point to a string using OutputTimePoint.
1641
std::string TimePointToString(const std::chrono::system_clock::time_point& time, bool useRFC3339 = false);
42+
std::string TimePointToString(const std::chrono::system_clock::time_point& time, TimeFacet facet);
1743

1844
// Gets the current time as a string. Can be used as a file name.
19-
std::string GetCurrentTimeForFilename();
45+
// Tries to make things a little bit shorter when shortTime == true.
46+
std::string GetCurrentTimeForFilename(bool shortTime = false);
2047

2148
// Gets the current date as a string to be used in the ARP registry.
2249
std::string GetCurrentDateForARP();

src/WindowsPackageManager/ConfigurationStaticFunctions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ namespace ConfigurationShim
9090
auto& diagnosticsLogger = m_threadGlobals.GetDiagnosticLogger();
9191
diagnosticsLogger.SetEnabledChannels(AppInstaller::Logging::Channel::All);
9292
diagnosticsLogger.SetLevel(AppInstaller::Logging::Level::Verbose);
93-
diagnosticsLogger.AddLogger(std::make_unique<AppInstaller::Logging::FileLogger>("ConfigStatics"sv));
93+
diagnosticsLogger.AddLogger(std::make_unique<AppInstaller::Logging::FileLogger>("WinGetCFG"sv));
9494

9595
if (IsConfigurationAvailable())
9696
{

0 commit comments

Comments
 (0)