Skip to content

Commit f231adc

Browse files
committed
Add Edit Source
1 parent 087ea0e commit f231adc

File tree

20 files changed

+424
-1
lines changed

20 files changed

+424
-1
lines changed

src/AppInstallerCLICore/Commands/SourceCommand.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ namespace AppInstaller::CLI
2121
std::make_unique<SourceListCommand>(FullName()),
2222
std::make_unique<SourceUpdateCommand>(FullName()),
2323
std::make_unique<SourceRemoveCommand>(FullName()),
24+
std::make_unique<SourceEditCommand>(FullName()),
2425
std::make_unique<SourceResetCommand>(FullName()),
2526
std::make_unique<SourceExportCommand>(FullName()),
2627
});
@@ -312,4 +313,37 @@ namespace AppInstaller::CLI
312313
Workflow::GetSourceListWithFilter <<
313314
Workflow::ExportSourceList;
314315
}
316+
317+
// Source Edit Command
318+
319+
std::vector<Argument> SourceEditCommand::GetArguments() const
320+
{
321+
return {
322+
Argument::ForType(Args::Type::SourceName).SetRequired(true),
323+
Argument::ForType(Args::Type::SourceExplicit),
324+
};
325+
}
326+
327+
Resource::LocString SourceEditCommand::ShortDescription() const
328+
{
329+
return { Resource::String::SourceEditCommandShortDescription };
330+
}
331+
332+
Resource::LocString SourceEditCommand::LongDescription() const
333+
{
334+
return { Resource::String::SourceEditCommandLongDescription };
335+
}
336+
337+
Utility::LocIndView SourceEditCommand::HelpLink() const
338+
{
339+
return s_SourceCommand_HelpLink;
340+
}
341+
342+
void SourceEditCommand::ExecuteInternal(Context& context) const
343+
{
344+
context <<
345+
Workflow::EnsureRunningAsAdmin <<
346+
Workflow::GetSourceListWithFilter <<
347+
Workflow::EditSources;
348+
}
315349
}

src/AppInstallerCLICore/Commands/SourceCommand.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,4 +121,19 @@ namespace AppInstaller::CLI
121121
protected:
122122
void ExecuteInternal(Execution::Context& context) const override;
123123
};
124+
125+
struct SourceEditCommand final : public Command
126+
{
127+
SourceEditCommand(std::string_view parent) : Command("edit", {}, parent, Settings::TogglePolicy::Policy::AllowedSources) {}
128+
129+
std::vector<Argument> GetArguments() const override;
130+
131+
Resource::LocString ShortDescription() const override;
132+
Resource::LocString LongDescription() const override;
133+
134+
Utility::LocIndView HelpLink() const override;
135+
136+
protected:
137+
void ExecuteInternal(Execution::Context& context) const override;
138+
};
124139
}

src/AppInstallerCLICore/Resources.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,10 @@ namespace AppInstaller::CLI::Resource
687687
WINGET_DEFINE_RESOURCE_STRINGID(SourceArgumentDescription);
688688
WINGET_DEFINE_RESOURCE_STRINGID(SourceCommandLongDescription);
689689
WINGET_DEFINE_RESOURCE_STRINGID(SourceCommandShortDescription);
690+
WINGET_DEFINE_RESOURCE_STRINGID(SourceEditCommandLongDescription);
691+
WINGET_DEFINE_RESOURCE_STRINGID(SourceEditCommandShortDescription);
692+
WINGET_DEFINE_RESOURCE_STRINGID(SourceEditOne);
693+
WINGET_DEFINE_RESOURCE_STRINGID(SourceEditNoChanges);
690694
WINGET_DEFINE_RESOURCE_STRINGID(SourceExplicitArgumentDescription);
691695
WINGET_DEFINE_RESOURCE_STRINGID(SourceExportCommandLongDescription);
692696
WINGET_DEFINE_RESOURCE_STRINGID(SourceExportCommandShortDescription);

src/AppInstallerCLICore/Workflows/SourceFlow.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,39 @@ namespace AppInstaller::CLI::Workflow
272272
}
273273
}
274274

275+
void EditSources(Execution::Context& context)
276+
{
277+
// We are assuming there is only one match, as SourceName is a required parameter.
278+
const std::vector<Repository::SourceDetails>& sources = context.Get<Data::SourceList>();
279+
bool isExplicit = context.Args.Contains(Args::Type::SourceExplicit);
280+
for (const auto& sd : sources)
281+
{
282+
// Get the current source with this name.
283+
Repository::Source currentSource{ sd.Name };
284+
285+
// Only permitting Explicit to be edited at this time.
286+
Repository::Source source{ sd.Name, isExplicit };
287+
288+
// Is anything being changed??
289+
if (!source.IsEditOfSource(currentSource))
290+
{
291+
context.Reporter.Info() << Resource::String::SourceEditNoChanges(Utility::LocIndView{ sd.Name }) << std::endl;
292+
continue;
293+
}
294+
295+
context.Reporter.Info() << Resource::String::SourceEditOne(Utility::LocIndView{ sd.Name }, Utility::LocIndView{ Utility::ConvertBoolToString(isExplicit) }) << std::endl;
296+
auto editFunction = [&](IProgressCallback& progress)->bool { return source.Edit(progress); };
297+
if (context.Reporter.ExecuteWithProgress(editFunction))
298+
{
299+
context.Reporter.Info() << Resource::String::Done << std::endl;
300+
}
301+
else
302+
{
303+
context.Reporter.Info() << Resource::String::Cancelled << std::endl;
304+
}
305+
}
306+
}
307+
275308
void QueryUserForSourceReset(Execution::Context& context)
276309
{
277310
if (!context.Args.Contains(Execution::Args::Type::ForceSourceReset))

src/AppInstallerCLICore/Workflows/SourceFlow.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,10 @@ namespace AppInstaller::CLI::Workflow
8383
// Inputs: None
8484
// Outputs: None
8585
void ForceInstalledCacheUpdate(Execution::Context& context);
86+
87+
// Edits a source in SourceList.
88+
// Required Args: SourceName
89+
// Inputs: SourceList
90+
// Outputs: None
91+
void EditSources(Execution::Context& context);
8692
}

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,20 @@ They can be configured through the settings file 'winget settings'.</value>
545545
<data name="SourceCommandShortDescription" xml:space="preserve">
546546
<value>Manage sources of packages</value>
547547
</data>
548+
<data name="SourceEditCommandLongDescription" xml:space="preserve">
549+
<value>Edit properties of an existing source. A source provides the data for you to discover and install packages. Only add a new source if you trust it as a secure location.</value>
550+
</data>
551+
<data name="SourceEditCommandShortDescription" xml:space="preserve">
552+
<value>Edit properties of a source</value>
553+
</data>
554+
<data name="SourceEditOne" xml:space="preserve">
555+
<value>Changing source: {0} to Explicit={1}...</value>
556+
<comment>{Locked="{0}","{1}"} Message displayed to inform the user about a registered repository source that is currently being edited. {0} is a placeholder replaced by the repository source name. {1} is a placeholder replaced by the changed value.</comment>
557+
</data>
558+
<data name="SourceEditNoChanges" xml:space="preserve">
559+
<value>The source named '{0}' is already in that desired state.</value>
560+
<comment>{Locked="{0}"} Message displayed to inform the user about a registered repository source that is currently being edited. {0} is a placeholder replaced by the repository source name.</comment>
561+
</data>
548562
<data name="SourceListArg" xml:space="preserve">
549563
<value>Argument</value>
550564
<comment>Value given to source.</comment>

src/AppInstallerCLITests/Sources.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,17 @@ constexpr std::string_view s_SingleSource = R"(
6666
IsTombstone: false
6767
)"sv;
6868

69+
constexpr std::string_view s_SingleSourceOverride = R"(
70+
Sources:
71+
- Name: winget-font
72+
Type: ""
73+
Arg: ""
74+
Data: ""
75+
IsTombstone: false
76+
IsOverride: true
77+
Explicit: false
78+
)"sv;
79+
6980
constexpr std::string_view s_SingleSourceMetadata = R"(
7081
Sources:
7182
- Name: testName
@@ -291,6 +302,40 @@ TEST_CASE("RepoSources_DefaultSourcesTombstoned", "[sources]")
291302
REQUIRE(sources.empty());
292303
}
293304

305+
306+
TEST_CASE("RepoSources_DefaultSourceOverride", "[sources]")
307+
{
308+
SetSetting(Stream::UserSources, s_EmptySources);
309+
310+
// Default font has explicit to true.
311+
// Font is at index 2 as it is the third one added.
312+
auto beforeOverride = GetSources();
313+
REQUIRE(beforeOverride.size() == c_DefaultSourceCount);
314+
REQUIRE(beforeOverride[2].Name == "winget-font");
315+
REQUIRE(beforeOverride[2].Arg == "https://cdn.winget.microsoft.com/fonts");
316+
REQUIRE(beforeOverride[2].Data == "Microsoft.Winget.Fonts.Source_8wekyb3d8bbwe");
317+
REQUIRE(beforeOverride[2].Type == "Microsoft.PreIndexed.Package");
318+
REQUIRE(beforeOverride[2].Origin == SourceOrigin::Default);
319+
REQUIRE(beforeOverride[2].Explicit == true);
320+
321+
SetSetting(Stream::UserSources, s_SingleSourceOverride);
322+
auto afterOverride = GetSources();
323+
324+
// The override will change the index value as the Default will be replaced by the override.
325+
// User sources have higher priority so the override will be at index 0.
326+
// We expect the same count, and the Name, Arg, Data, and Type properties to all be identical.
327+
// Only the name is defined in the override setting so all others should be propertly populated.
328+
REQUIRE(afterOverride.size() == c_DefaultSourceCount);
329+
REQUIRE(afterOverride[0].Name == beforeOverride[2].Name);
330+
REQUIRE(afterOverride[0].Arg == beforeOverride[2].Arg);
331+
REQUIRE(afterOverride[0].Data == beforeOverride[2].Data);
332+
REQUIRE(afterOverride[0].Type == beforeOverride[2].Type);
333+
334+
// The only properties we expect to be different are the Origin, which is now User, and Explicit.
335+
REQUIRE(afterOverride[0].Origin == SourceOrigin::User);
336+
REQUIRE(afterOverride[0].Explicit == false);
337+
}
338+
294339
TEST_CASE("RepoSources_SingleSource", "[sources]")
295340
{
296341
SetSetting(Stream::UserSources, s_SingleSource);

src/AppInstallerCLITests/TestSource.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,15 @@ namespace TestCommon
454454
return true;
455455
}
456456

457+
bool TestSourceFactory::Edit(const SourceDetails& details, IProgressCallback&)
458+
{
459+
if (OnEdit)
460+
{
461+
OnEdit(details);
462+
}
463+
return true;
464+
}
465+
457466
// Make copies of self when requested.
458467
TestSourceFactory::operator std::function<std::unique_ptr<ISourceFactory>()>()
459468
{
@@ -466,6 +475,12 @@ namespace TestCommon
466475
return source.Add(progress);
467476
}
468477

478+
bool EditSource(const AppInstaller::Repository::SourceDetails& details, AppInstaller::IProgressCallback& progress)
479+
{
480+
Repository::Source source{ details.Name, details.Explicit };
481+
return source.Edit(progress);
482+
}
483+
469484
bool UpdateSource(std::string_view name, AppInstaller::IProgressCallback& progress)
470485
{
471486
Repository::Source source{ name };

src/AppInstallerCLITests/TestSource.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ namespace TestCommon
187187
using AddFunctor = std::function<void(AppInstaller::Repository::SourceDetails&)>;
188188
using UpdateFunctor = std::function<void(const AppInstaller::Repository::SourceDetails&)>;
189189
using RemoveFunctor = std::function<void(const AppInstaller::Repository::SourceDetails&)>;
190+
using EditFunctor = std::function<void(const AppInstaller::Repository::SourceDetails&)>;
190191

191192
TestSourceFactory(OpenFunctor open) : OnOpen(std::move(open)) {}
192193
TestSourceFactory(OpenFunctorWithCustomHeader open) : OnOpenWithCustomHeader(std::move(open)) {}
@@ -197,6 +198,7 @@ namespace TestCommon
197198
bool Add(AppInstaller::Repository::SourceDetails& details, AppInstaller::IProgressCallback&) override;
198199
bool Update(const AppInstaller::Repository::SourceDetails& details, AppInstaller::IProgressCallback&) override;
199200
bool Remove(const AppInstaller::Repository::SourceDetails& details, AppInstaller::IProgressCallback&) override;
201+
bool Edit(const AppInstaller::Repository::SourceDetails& details, AppInstaller::IProgressCallback&) override;
200202

201203
// Make copies of self when requested.
202204
operator std::function<std::unique_ptr<AppInstaller::Repository::ISourceFactory>()>();
@@ -207,9 +209,11 @@ namespace TestCommon
207209
AddFunctor OnAdd;
208210
UpdateFunctor OnUpdate;
209211
RemoveFunctor OnRemove;
212+
EditFunctor OnEdit;
210213
};
211214

212215
bool AddSource(const AppInstaller::Repository::SourceDetails& details, AppInstaller::IProgressCallback& progress);
216+
bool EditSource(const AppInstaller::Repository::SourceDetails& details, AppInstaller::IProgressCallback& progress);
213217
bool UpdateSource(std::string_view name, AppInstaller::IProgressCallback& progress);
214218
bool RemoveSource(std::string_view name, AppInstaller::IProgressCallback& progress);
215219
AppInstaller::Repository::Source OpenSource(std::string_view name, AppInstaller::IProgressCallback& progress);

src/AppInstallerRepositoryCore/Microsoft/ConfigurableTestSourceFactory.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,11 @@ namespace AppInstaller::Repository::Microsoft
154154
{
155155
return true;
156156
}
157+
158+
bool Edit(const SourceDetails&, IProgressCallback&) override final
159+
{
160+
return true;
161+
}
157162
};
158163
}
159164

0 commit comments

Comments
 (0)