Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
dac55b5
Prototype of import/export
Jan 6, 2021
4d6c28a
Preserve unavailable packages on export; add option for exact versions
Jan 13, 2021
60109c5
typo
Jan 13, 2021
01c6b86
Lowercase command names
Jan 13, 2021
c89e8a0
Remove query arguments for export (except source)
Jan 21, 2021
6e0830f
Use Workflow::VerifyFile for import
Jan 21, 2021
d015f37
Move argument definitions to be in command definitions
Jan 21, 2021
9842b1f
Find sources by identifier instead of argument
Jan 22, 2021
2f46348
Style changes from review & better logging/reporting
Jan 26, 2021
c6408d7
Add tests for workflow & detect installed packages
Jan 29, 2021
8122ea8
Add unit tests for JSON read/write
Jan 29, 2021
8b07d23
Spell checking
Feb 1, 2021
c82d9cb
Disable schema validation
Feb 2, 2021
3c45df8
Add E2E tests
Feb 2, 2021
86101a8
Track installed version in test exe installer
Feb 2, 2021
508d094
Uninstall test exe before tests
Feb 3, 2021
b176066
Spell checking
Feb 3, 2021
1a30962
Fix test failure
Feb 3, 2021
576c051
Move and rename packages schema file
Feb 5, 2021
20aba26
Merge branch 'master' into ImportExport
Feb 8, 2021
5bcd4a2
Spell checking
Feb 8, 2021
33ba202
Fix error codes in tests after merge
Feb 9, 2021
660387d
Apply suggestions from code review
lechacon Feb 11, 2021
20984c6
Remove exact versions import argument
Feb 11, 2021
7eb3359
Match sources with identifier and type
Feb 11, 2021
4c93054
Add execution stages
Feb 11, 2021
08b1604
Add --force argument to skip missing packages
Feb 11, 2021
dc8bcad
Rename ParseJson -> TryParseJson
Feb 11, 2021
f7a9c43
Use workflow task for building Sources vector
Feb 11, 2021
4b59e1a
Fix tests
Feb 11, 2021
8b45f6d
Change composite search behavior from flag to enum
Feb 11, 2021
58f6fe4
Address comments from review
Feb 12, 2021
1357453
Update behavior around versions
Feb 12, 2021
a09ad02
Fix tests
Feb 12, 2021
abd0e4c
Don't check that installed version is available unless needed
Feb 13, 2021
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
4 changes: 4 additions & 0 deletions .github/actions/spelling/allow.txt
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,7 @@ VOS
vso
wapproj
wchar
wcout
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not in the product code or tests directly, but in a standalone .exe used as a test installer. It was mixing narrow and wide chars and that was getting complicated, but it didn't seem worth it to add conversion between them there, so I moved it all to wide. It should be fine as it's independent of everything else.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only thing I'd note is that by using it here instead of, e.g. just telling the bot to ignore the file entirely, the bot will never warn about the next violation.

Think of it like page-fault protection.

Obviously reviewers are responsible for the content, so in theory some reviewer should catch future incursions.

(Just feedback from the peanut gallery.)

wcsicmp
webpage
wekyb
Expand All @@ -465,11 +466,14 @@ winsqlite
wix
wmain
woah
wofstream
workflow
wostream
wpfn
wrl
WStr
wstring
wstringstream
www
xamarin
xlang
Expand Down
3 changes: 3 additions & 0 deletions .github/actions/spelling/expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,9 @@ usersettingstest
USHORT
Utils
UWP
validator
valijson
valueiterator
vamus
VERSI
VERSIE
Expand Down
10 changes: 10 additions & 0 deletions doc/Settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,13 @@ While work is in progress on uninstall, the command is hidden behind a feature t
"uninstall": true
},
```

### importExport

While work is in progress for import and export, the command is hidden behind a feature toggle. One can enable it as below:

```
"experimentalFeatures": {
"importExport": true
},
```
97 changes: 97 additions & 0 deletions schemas/JSON/packages/packages.schema.1.0.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
{
"$id": "https://aka.ms/winget-packages.schema.json",
"$schema": "https://json-schema.org/draft/2019-09/schema#",

"title": "winget Packages List Schema",
"description": "Describes a list of packages for batch installs",

"type": "object",
"required": [ "WinGetVersion", "Sources" ],
"additionalProperties": true,

"properties": {
"WinGetVersion": {
Comment thread
florelis marked this conversation as resolved.
"description": "Version of winget that generated this file",
"type": "string",
"pattern": "^[0-9]+\\.[0-9]\\.[0-9]$"
},

"CreationDate": {
"description": "Date when this list was generated",
"type": "string",
"format": "date-time"
},

"Sources": {
"description": "Sources from which each package comes from",
"type": "array",

"items": {
"description": "A source and the list of packages to install from it",
"type": "object",
"required": [ "SourceDetails", "Packages" ],
"additionalProperties": true,

"properties": {
"SourceDetails": {
"description": "Details about this source",
"type": "object",
"required": [ "Name", "Identifier", "Argument", "Type" ],
"additionalProperties": true,

"properties": {
"Name": {
"description": "Name of the source",
"type": "string"
},

"Identifier": {
"description": "Identifier for the source",
"type": "string"
},

"Argument": {
"description": "Argument used to install the source",
"type": "string"
},

"Type": {
"description": "Type of the source",
"type": "string"
}
}
},

"Packages": {
"description": "Packages installed from this source",
"type": "array",
"required": [ "Id" ],
"minItems": 1,

"items": {
"description": "A package to be installed from this source",
"type": "object",
"additionalProperties": true,
"properties": {
"Id": {
"description": "Package ID",
"type": "string"
},

"Version": {
"description": "Package version",
"type": "string"
},

"Channel": {
"description": "Package channel",
"type": "string"
}
}
}
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@
"description": "Enable the uninstall command while it is in development",
"type": "boolean",
"default": false
},
"importExport": {
"description": "Enable the import and export commands",
"type": "boolean",
"default": false
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/AppInstallerCLI.sln
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Project", "Project", "{8D53
..\azure-pipelines.yml = ..\azure-pipelines.yml
..\cgmanifest.json = ..\cgmanifest.json
..\README.md = ..\README.md
..\doc\packages.schema.json = ..\doc\packages.schema.json
..\doc\Settings.md = ..\doc\Settings.md
..\doc\settings.schema.json = ..\doc\settings.schema.json
EndProjectSection
Expand Down
8 changes: 8 additions & 0 deletions src/AppInstallerCLICore/AppInstallerCLICore.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@
<ClInclude Include="Command.h" />
<ClInclude Include="Commands\CompleteCommand.h" />
<ClInclude Include="Commands\ExperimentalCommand.h" />
<ClInclude Include="Commands\ExportCommand.h" />
<ClInclude Include="Commands\ImportCommand.h" />
<ClInclude Include="Commands\FeaturesCommand.h" />
<ClInclude Include="Commands\HashCommand.h" />
<ClInclude Include="Commands\ListCommand.h" />
Expand All @@ -201,7 +203,9 @@
<ClInclude Include="Search\Search.h" />
<ClInclude Include="TableOutput.h" />
<ClInclude Include="VTSupport.h" />
<ClInclude Include="PackageCollection.h" />
<ClInclude Include="Workflows\CompletionFlow.h" />
<ClInclude Include="Workflows\ImportExportFlow.h" />
<ClInclude Include="Workflows\MSStoreInstallerHandler.h" />
<ClInclude Include="Workflows\ShellExecuteInstallerHandler.h" />
<ClInclude Include="Workflows\InstallFlow.h" />
Expand All @@ -213,11 +217,14 @@
<ClInclude Include="Workflows\WorkflowBase.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="Commands\ImportCommand.cpp" />
<ClCompile Include="PackageCollection.cpp" />
<ClCompile Include="Argument.cpp" />
<ClCompile Include="ChannelStreams.cpp" />
<ClCompile Include="Command.cpp" />
<ClCompile Include="Commands\CompleteCommand.cpp" />
<ClCompile Include="Commands\ExperimentalCommand.cpp" />
<ClCompile Include="Commands\ExportCommand.cpp" />
<ClCompile Include="Commands\FeaturesCommand.cpp" />
<ClCompile Include="Commands\HashCommand.cpp" />
<ClCompile Include="Commands\ListCommand.cpp" />
Expand All @@ -241,6 +248,7 @@
<ClCompile Include="Resources.cpp" />
<ClCompile Include="VTSupport.cpp" />
<ClCompile Include="Workflows\CompletionFlow.cpp" />
<ClCompile Include="Workflows\ImportExportFlow.cpp" />
<ClCompile Include="Workflows\MSStoreInstallerHandler.cpp" />
<ClCompile Include="Workflows\ShellExecuteInstallerHandler.cpp" />
<ClCompile Include="Workflows\InstallFlow.cpp" />
Expand Down
31 changes: 27 additions & 4 deletions src/AppInstallerCLICore/AppInstallerCLICore.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Commands">
<UniqueIdentifier>{4b0dcf8b-b4a1-47e5-9c28-e8a3440178e6}</UniqueIdentifier>
</Filter>
Expand Down Expand Up @@ -141,6 +137,21 @@
<ClInclude Include="Workflows\UninstallFlow.h">
<Filter>Workflows</Filter>
</ClInclude>
<ClInclude Include="Commands\ExportCommand.h">
<Filter>Commands</Filter>
</ClInclude>
<ClInclude Include="PackageCollection.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Workflows\ImportExportFlow.h">
<Filter>Workflows</Filter>
</ClInclude>
<ClInclude Include="Commands\ImportCommand.h">
<Filter>Commands</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
Expand Down Expand Up @@ -248,6 +259,18 @@
<ClCompile Include="Workflows\UninstallFlow.cpp">
<Filter>Workflows</Filter>
</ClCompile>
<ClCompile Include="Commands\ExportCommand.cpp">
<Filter>Commands</Filter>
</ClCompile>
<ClCompile Include="PackageCollection.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Workflows\ImportExportFlow.cpp">
<Filter>Workflows</Filter>
</ClCompile>
<ClCompile Include="Commands\ImportCommand.cpp">
<Filter>Commands</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="PropertySheet.props" />
Expand Down
66 changes: 66 additions & 0 deletions src/AppInstallerCLICore/Commands/ExportCommand.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#include "pch.h"
#include "ExportCommand.h"
#include "Workflows/CompletionFlow.h"
#include "Workflows/ImportExportFlow.h"
#include "Workflows/WorkflowBase.h"
#include "Resources.h"

namespace AppInstaller::CLI
{
using namespace std::string_view_literals;

std::vector<Argument> ExportCommand::GetArguments() const
{
return {
Argument{ "output", 'o', Execution::Args::Type::OutputFile, Resource::String::OutputFileArgumentDescription, ArgumentType::Positional, true },
Argument{ "source", 's', Execution::Args::Type::Source, Resource::String::ExportSourceArgumentDescription, ArgumentType::Standard },
Argument{ "include-versions", Argument::NoAlias, Execution::Args::Type::IncludeVersions, Resource::String::ExportIncludeVersionsArgumentDescription, ArgumentType::Flag },
};
}

Resource::LocString ExportCommand::ShortDescription() const
{
return { Resource::String::ExportCommandShortDescription };
}

Resource::LocString ExportCommand::LongDescription() const
{
return { Resource::String::ExportCommandLongDescription };
}

void ExportCommand::Complete(Execution::Context& context, Execution::Args::Type valueType) const
{
if (valueType == Execution::Args::Type::OutputFile)
{
// Intentionally output nothing to allow pass through to filesystem.
return;
}

if (valueType == Execution::Args::Type::Source)
{
context << Workflow::CompleteSourceName;
return;
}
}

std::string ExportCommand::HelpLink() const
{
// TODO: point to correct location
return "https://aka.ms/winget-command-export";
}

void ExportCommand::ExecuteInternal(Execution::Context& context) const
{
context <<
Comment thread
florelis marked this conversation as resolved.
Workflow::ReportExecutionStage(Workflow::ExecutionStage::Discovery) <<
Workflow::OpenSource <<
Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed) <<
Workflow::SearchSourceForMany <<
Workflow::EnsureMatchesFromSearchResult(true) <<
Workflow::SelectVersionsToExport <<
Workflow::ReportExecutionStage(Workflow::ExecutionStage::Execution) <<
Workflow::WriteImportFile;
}
}
25 changes: 25 additions & 0 deletions src/AppInstallerCLICore/Commands/ExportCommand.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#pragma once
#include "Command.h"

namespace AppInstaller::CLI
{
// Command to get the set of installed packages on the system.
struct ExportCommand final : public Command
{
ExportCommand(std::string_view parent) : Command("export", parent, Settings::ExperimentalFeature::Feature::ExperimentalImportExport) {}

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

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

void Complete(Execution::Context& context, Execution::Args::Type valueType) const override;

std::string HelpLink() const override;

protected:
void ExecuteInternal(Execution::Context& context) const override;
};
}
Loading