Skip to content

Commit 8a805cc

Browse files
authored
Fix winget after a call to winget settings export (microsoft#2767)
1 parent 23f9942 commit 8a805cc

15 files changed

Lines changed: 138 additions & 82 deletions

File tree

src/AppInstallerCLICore/Command.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ namespace AppInstaller::CLI
3030
std::string_view parent,
3131
Command::Visibility visibility,
3232
Settings::ExperimentalFeature::Feature feature,
33-
Settings::TogglePolicy::Policy groupPolicy) :
34-
m_name(name), m_aliases(std::move(aliases)), m_visibility(visibility), m_feature(feature), m_groupPolicy(groupPolicy)
33+
Settings::TogglePolicy::Policy groupPolicy,
34+
CommandOutputFlags outputFlags) :
35+
m_name(name), m_aliases(std::move(aliases)), m_visibility(visibility), m_feature(feature), m_groupPolicy(groupPolicy), m_outputFlags(outputFlags)
3536
{
3637
if (!parent.empty())
3738
{
@@ -933,7 +934,8 @@ namespace AppInstaller::CLI
933934
{
934935
try
935936
{
936-
if (!Settings::User().GetWarnings().empty())
937+
if (!Settings::User().GetWarnings().empty() &&
938+
!WI_IsFlagSet(command->GetOutputFlags(), CommandOutputFlags::IgnoreSettingsWarnings))
937939
{
938940
context.Reporter.Warn() << Resource::String::SettingsWarnings << std::endl;
939941
}

src/AppInstallerCLICore/Command.h

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,15 @@ namespace AppInstaller::CLI
4444
std::vector<Utility::LocIndString> m_params;
4545
};
4646

47+
// Flags to control the behavior of the command output.
48+
enum class CommandOutputFlags : int
49+
{
50+
None = 0x0,
51+
IgnoreSettingsWarnings = 0x1,
52+
};
53+
54+
DEFINE_ENUM_FLAG_OPERATORS(CommandOutputFlags);
55+
4756
struct Command
4857
{
4958
// Controls the visibility of the field.
@@ -57,17 +66,27 @@ namespace AppInstaller::CLI
5766

5867
Command(std::string_view name, std::string_view parent) :
5968
Command(name, {}, parent) {}
60-
Command(std::string_view name,std::vector<std::string_view> aliases, std::string_view parent) :
69+
Command(std::string_view name, std::vector<std::string_view> aliases, std::string_view parent) :
6170
Command(name, aliases, parent, Settings::ExperimentalFeature::Feature::None) {}
62-
Command(std::string_view name,std::vector<std::string_view> aliases, std::string_view parent, Command::Visibility visibility) :
71+
Command(std::string_view name, std::string_view parent, CommandOutputFlags outputFlags) :
72+
Command(name, {}, parent, Command::Visibility::Show, Settings::ExperimentalFeature::Feature::None, Settings::TogglePolicy::Policy::None, outputFlags) {}
73+
Command(std::string_view name, std::vector<std::string_view> aliases, std::string_view parent, Command::Visibility visibility) :
6374
Command(name, aliases, parent, visibility, Settings::ExperimentalFeature::Feature::None) {}
64-
Command(std::string_view name,std::vector<std::string_view> aliases, std::string_view parent, Settings::ExperimentalFeature::Feature feature) :
75+
Command(std::string_view name, std::vector<std::string_view> aliases, std::string_view parent, Settings::ExperimentalFeature::Feature feature) :
6576
Command(name, aliases, parent, Command::Visibility::Show, feature) {}
66-
Command(std::string_view name,std::vector<std::string_view> aliases, std::string_view parent, Settings::TogglePolicy::Policy groupPolicy) :
67-
Command(name, aliases, parent, Command::Visibility::Show, Settings::ExperimentalFeature::Feature::None, groupPolicy) {}
68-
Command(std::string_view name,std::vector<std::string_view> aliases, std::string_view parent, Command::Visibility visibility, Settings::ExperimentalFeature::Feature feature) :
69-
Command(name, aliases, parent, visibility, feature, Settings::TogglePolicy::Policy::None) {}
70-
Command(std::string_view name,std::vector<std::string_view> aliases, std::string_view parent, Command::Visibility visibility, Settings::ExperimentalFeature::Feature feature, Settings::TogglePolicy::Policy groupPolicy);
77+
Command(std::string_view name, std::vector<std::string_view> aliases, std::string_view parent, Settings::TogglePolicy::Policy groupPolicy) :
78+
Command(name, aliases, parent, Command::Visibility::Show, Settings::ExperimentalFeature::Feature::None, groupPolicy, CommandOutputFlags::None) {}
79+
Command(std::string_view name, std::vector<std::string_view> aliases, std::string_view parent, Command::Visibility visibility, Settings::ExperimentalFeature::Feature feature) :
80+
Command(name, aliases, parent, visibility, feature, Settings::TogglePolicy::Policy::None, CommandOutputFlags::None) {}
81+
82+
Command(std::string_view name,
83+
std::vector<std::string_view> aliases,
84+
std::string_view parent,
85+
Command::Visibility visibility,
86+
Settings::ExperimentalFeature::Feature feature,
87+
Settings::TogglePolicy::Policy groupPolicy,
88+
CommandOutputFlags outputFlags);
89+
7190
virtual ~Command() = default;
7291

7392
Command(const Command&) = default;
@@ -85,6 +104,7 @@ namespace AppInstaller::CLI
85104
Command::Visibility GetVisibility() const;
86105
Settings::ExperimentalFeature::Feature Feature() const { return m_feature; }
87106
Settings::TogglePolicy::Policy GroupPolicy() const { return m_groupPolicy; }
107+
CommandOutputFlags GetOutputFlags() const { return m_outputFlags; }
88108

89109
virtual std::vector<std::unique_ptr<Command>> GetCommands() const { return {}; }
90110
virtual std::vector<Argument> GetArguments() const { return {}; }
@@ -118,6 +138,7 @@ namespace AppInstaller::CLI
118138
Command::Visibility m_visibility;
119139
Settings::ExperimentalFeature::Feature m_feature;
120140
Settings::TogglePolicy::Policy m_groupPolicy;
141+
CommandOutputFlags m_outputFlags;
121142
};
122143

123144
template <typename Container>

src/AppInstallerCLICore/Commands/RootCommand.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ using namespace AppInstaller::Utility::literals;
2727

2828
namespace AppInstaller::CLI
2929
{
30+
using namespace Settings;
31+
3032
namespace
3133
{
3234
void OutputGroupPolicySourceList(Execution::Context& context, const std::vector<Settings::SourceFromPolicy>& sources, Resource::StringId header)
@@ -193,7 +195,7 @@ namespace AppInstaller::CLI
193195
};
194196

195197
info << std::endl << Resource::String::Logs << ": "_liv << Runtime::GetPathTo(Runtime::PathName::DefaultLogLocationForDisplay).u8string() << std::endl;
196-
info << std::endl << Resource::String::UserSettings << ": "_liv << Runtime::GetPathTo(Runtime::PathName::UserSettingsFileLocationForDisplay).u8string() << std::endl;
198+
info << std::endl << Resource::String::UserSettings << ": "_liv << UserSettings::SettingsFilePath(true).u8string() << std::endl;
197199

198200
info << std::endl;
199201

src/AppInstallerCLICore/Commands/SettingsCommand.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ namespace AppInstaller::CLI
2424

2525
struct SettingsExportCommand final : public Command
2626
{
27-
SettingsExportCommand(std::string_view parent) : Command("export", parent) {}
27+
SettingsExportCommand(std::string_view parent) : Command("export", parent, CommandOutputFlags::IgnoreSettingsWarnings) {}
2828

2929
Resource::LocString ShortDescription() const override;
3030
Resource::LocString LongDescription() const override;

src/AppInstallerCLICore/Commands/SourceCommand.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ namespace AppInstaller::CLI
106106

107107
struct SourceExportCommand final : public Command
108108
{
109-
SourceExportCommand(std::string_view parent) : Command("export", parent) {}
109+
SourceExportCommand(std::string_view parent) : Command("export", parent, CommandOutputFlags::IgnoreSettingsWarnings) {}
110110

111111
std::vector<Argument> GetArguments() const override;
112112

src/AppInstallerCLICore/Workflows/SettingsFlow.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ namespace AppInstaller::CLI::Workflow
2020
{
2121
root["$schema"] = "https://aka.ms/winget-settings-export.schema.json";
2222
root["adminSettings"] = Json::ValueType::objectValue;
23-
root["userSettingsFile"] = Runtime::GetPathTo(Runtime::PathName::UserSettingsFileLocation).u8string();
23+
root["userSettingsFile"] = UserSettings::SettingsFilePath().u8string();
2424
}
2525

2626
void AddAdminSetting(AdminSetting setting)

src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1541,4 +1541,7 @@ Please specify one of them using the --source option to proceed.</value>
15411541
<data name="UserSettings" xml:space="preserve">
15421542
<value>User Settings</value>
15431543
</data>
1544+
<data name="SettingsWarningUsingDefault" xml:space="preserve">
1545+
<value>Settings file couldn't load. Using default values.</value>
1546+
</data>
15441547
</root>

src/AppInstallerCLITests/UserSettings.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -419,12 +419,16 @@ TEST_CASE("SettingsPortablePackageUserRoot", "[settings]")
419419
SECTION("Relative path")
420420
{
421421
DeleteUserSettingsFiles();
422-
std::string_view json = R"({ "installBehavior": { "portablePackageUserRoot": %LOCALAPPDATA%/Portable/Root } })";
422+
std::string_view json = R"({ "installBehavior": { "portablePackageUserRoot": "%LOCALAPPDATA%/Portable/Root" } })";
423423
SetSetting(Stream::PrimaryUserSettings, json);
424424
UserSettingsTest userSettingTest;
425425

426426
REQUIRE(userSettingTest.Get<Setting::PortablePackageUserRoot>().empty());
427-
REQUIRE(userSettingTest.GetWarnings().size() == 1);
427+
428+
auto warnings = userSettingTest.GetWarnings();
429+
REQUIRE(warnings.size() == 1);
430+
REQUIRE(warnings[0].Message == AppInstaller::StringResource::String::SettingsWarningInvalidFieldValue);
431+
REQUIRE(warnings[0].Path == ".installBehavior.portablePackageUserRoot");
428432
}
429433
SECTION("Valid path")
430434
{
@@ -443,12 +447,16 @@ TEST_CASE("SettingsPortablePackageMachineRoot", "[settings]")
443447
SECTION("Relative path")
444448
{
445449
DeleteUserSettingsFiles();
446-
std::string_view json = R"({ "installBehavior": { "portablePackageMachineRoot": %LOCALAPPDATA%/Portable/Root } })";
450+
std::string_view json = R"({ "installBehavior": { "portablePackageMachineRoot": "%LOCALAPPDATA%/Portable/Root" } })";
447451
SetSetting(Stream::PrimaryUserSettings, json);
448452
UserSettingsTest userSettingTest;
449453

450454
REQUIRE(userSettingTest.Get<Setting::PortablePackageMachineRoot>().empty());
451-
REQUIRE(userSettingTest.GetWarnings().size() == 1);
455+
456+
auto warnings = userSettingTest.GetWarnings();
457+
REQUIRE(warnings.size() == 1);
458+
REQUIRE(warnings[0].Message == AppInstaller::StringResource::String::SettingsWarningInvalidFieldValue);
459+
REQUIRE(warnings[0].Path == ".installBehavior.portablePackageMachineRoot");
452460
}
453461
SECTION("Valid path")
454462
{

src/AppInstallerCommonCore/Filesystem.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,4 +201,41 @@ namespace AppInstaller::Filesystem
201201
return path;
202202
}
203203
}
204+
205+
void ReplaceCommonPathPrefix(std::filesystem::path& source, const std::filesystem::path& prefix, std::string_view replacement)
206+
{
207+
auto prefixItr = prefix.begin();
208+
auto sourceItr = source.begin();
209+
210+
while (prefixItr != prefix.end() && sourceItr != source.end())
211+
{
212+
if (*prefixItr != *sourceItr)
213+
{
214+
break;
215+
}
216+
217+
++prefixItr;
218+
++sourceItr;
219+
}
220+
221+
// Only replace source if we found all of prefix
222+
if (prefixItr == prefix.end())
223+
{
224+
std::filesystem::path temp{ replacement };
225+
226+
for (; sourceItr != source.end(); ++sourceItr)
227+
{
228+
temp /= *sourceItr;
229+
}
230+
231+
source = std::move(temp);
232+
}
233+
}
234+
235+
std::filesystem::path GetKnownFolderPath(const KNOWNFOLDERID& id)
236+
{
237+
wil::unique_cotaskmem_string knownFolder = nullptr;
238+
THROW_IF_FAILED(SHGetKnownFolderPath(id, KF_FLAG_NO_ALIAS | KF_FLAG_DONT_VERIFY | KF_FLAG_NO_PACKAGE_REDIRECTION, NULL, &knownFolder));
239+
return knownFolder.get();
240+
}
204241
}

src/AppInstallerCommonCore/Public/AppInstallerRuntime.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,6 @@ namespace AppInstaller::Runtime
6262
PortableLinksUserLocation,
6363
// The location where symlinks to portable packages are stored under machine scope.
6464
PortableLinksMachineLocation,
65-
// The location of the user settings json file.
66-
UserSettingsFileLocation,
67-
// The location of the user settings json file, anonymized using environment variables.
68-
UserSettingsFileLocationForDisplay,
6965
};
7066

7167
// The principal that an ACE applies to.

0 commit comments

Comments
 (0)