Skip to content

Add license reporting and "vcpkg license-report" command. #1514

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jun 4, 2025
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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "vcpkg-license-apache-and-boost",
"version": "0",
"license": "BSL-1.0 AND Apache-2.0"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
8 changes: 8 additions & 0 deletions azure-pipelines/e2e-ports/vcpkg-license-bsd-on-mit/vcpkg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "vcpkg-license-bsd-on-mit",
"version": "0",
"license": "BSD-3-Clause",
"dependencies": [
"vcpkg-license-mit"
]
}
1 change: 1 addition & 0 deletions azure-pipelines/e2e-ports/vcpkg-license-bsd/portfile.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
5 changes: 5 additions & 0 deletions azure-pipelines/e2e-ports/vcpkg-license-bsd/vcpkg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "vcpkg-license-bsd",
"version": "0",
"license": "BSD-3-Clause"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
26 changes: 26 additions & 0 deletions azure-pipelines/e2e-ports/vcpkg-license-features/vcpkg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "vcpkg-license-features",
"version": "0",
"features": {
"apache-2": {
"description": "Apache 2.0 license feature",
"license": "Apache-2.0"
},
"boost": {
"description": "Boost license feature",
"license": "BSL-1.0"
},
"bsd-3-clause": {
"description": "BSD-3-Clause license feature",
"license": "BSD-3-Clause"
},
"mit": {
"description": "MIT license feature",
"license": "MIT"
},
"null": {
"description": "Null license feature",
"license": null
}
}
}
1 change: 1 addition & 0 deletions azure-pipelines/e2e-ports/vcpkg-license-mit/portfile.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
5 changes: 5 additions & 0 deletions azure-pipelines/e2e-ports/vcpkg-license-mit/vcpkg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "vcpkg-license-mit",
"version": "0",
"license": "MIT"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
5 changes: 5 additions & 0 deletions azure-pipelines/e2e-ports/vcpkg-license-null/vcpkg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "vcpkg-license-null",
"version": "0",
"license": null
}
30 changes: 4 additions & 26 deletions azure-pipelines/e2e-specs/autocomplete-posh-vcpkg.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ BeforeAll {
$VcpkgPredefined = @{
CommandList = @(
'acquire_project', 'acquire', 'activate', 'add', 'create', 'deactivate', 'depend-info', 'edit', 'env'
'export', 'fetch', 'find', 'format-feature-baseline', 'format-manifest', 'hash', 'help', 'install', 'integrate', 'list', 'new', 'owns'
'portsdiff', 'remove', 'search', 'update', 'upgrade', 'use', 'version', 'x-add-version', 'x-check-support'
'x-init-registry', 'x-package-info', 'x-regenerate', 'x-set-installed', 'x-test-features', 'x-update-baseline'
'x-update-registry', 'x-vsinstances'
'export', 'fetch', 'find', 'format-feature-baseline', 'format-manifest', 'hash', 'help', 'install', 'integrate',
'license-report', 'list', 'new', 'owns', 'portsdiff', 'remove', 'search', 'update', 'upgrade', 'use', 'version',
'x-add-version', 'x-check-support', 'x-init-registry', 'x-package-info', 'x-regenerate', 'x-set-installed',
'x-test-features', 'x-update-baseline', 'x-update-registry', 'x-vsinstances'
)
CommonParameterList = @()
CommandOptionList = @{
Expand Down Expand Up @@ -67,28 +67,6 @@ Describe 'Prerequisites tests' {
'Complete-InputCaret^' | Complete-InputCaret | Should -Contain 'Complete-InputCaret'
}
}

Context 'Exist module and command tests' {
It 'Should imported module posh-vcpkg' {
(Get-Module -Name posh-vcpkg).Name | Should -Be 'posh-vcpkg'
}

It 'Should version greater than or equal 0.0.2' {
(Get-Module posh-vcpkg).Version | Should -BeGreaterOrEqual '0.0.2'
}

It 'Should have executable vcpkg' {
$vcpkgExe | Should -Exist
}

It 'Should have command vcpkg' {
Get-Command -Name vcpkg | Should -Not -BeNullOrEmpty
}

It 'Should command vcpkg is the executable' {
(Get-Command -Name vcpkg).Path | Should -Be $vcpkgExe.FullName
}
}
}

Describe 'Complete basic tests' {
Expand Down
179 changes: 179 additions & 0 deletions azure-pipelines/end-to-end-tests-dir/license-report.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
. $PSScriptRoot/../end-to-end-tests-prelude.ps1

[string]$output = Run-VcpkgAndCaptureOutput @commonArgs license-report "--x-builtin-ports-root=$PSScriptRoot/../e2e-ports"
Throw-IfFailed
Throw-IfNonEqual -Actual $output -Expected @"
There are no installed packages, and thus no licenses of installed packages. Did you mean to install something first?

"@

$output = Run-VcpkgAndCaptureOutput @commonArgs install "--x-builtin-ports-root=$PSScriptRoot/../e2e-ports" vcpkg-license-bsd vcpkg-license-mit
Throw-IfFailed
Throw-IfNonContains -Actual $output -Expected @"
Packages installed in this vcpkg installation declare the following licenses:
BSD-3-Clause
MIT
"@

$output = Run-VcpkgAndCaptureOutput @commonArgs license-report "--x-builtin-ports-root=$PSScriptRoot/../e2e-ports"
Throw-IfFailed
Throw-IfNonEqual -Actual $output -Expected @"
Installed contents are licensed to you by owners. Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.
Installed packages declare the following licenses:
BSD-3-Clause
MIT

"@

# Note that the MIT license from the already installed package is not displayed for the install
$output = Run-VcpkgAndCaptureOutput @commonArgs install "--x-builtin-ports-root=$PSScriptRoot/../e2e-ports" vcpkg-license-bsd-on-mit
Throw-IfFailed
Throw-IfNonContains -Actual $output -Expected @"
Packages installed in this vcpkg installation declare the following licenses:
BSD-3-Clause
"@

$output = Run-VcpkgAndCaptureOutput @commonArgs license-report "--x-builtin-ports-root=$PSScriptRoot/../e2e-ports"
Throw-IfFailed
Throw-IfNonEqual -Actual $output -Expected @"
Installed contents are licensed to you by owners. Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.
Installed packages declare the following licenses:
BSD-3-Clause
MIT

"@

# Empty port == no license field set at all
$output = Run-VcpkgAndCaptureOutput @commonArgs install "--x-builtin-ports-root=$PSScriptRoot/../e2e-ports" vcpkg-empty-port
Throw-IfFailed
Throw-IfNonContains -Actual $output -Expected @"
Installed contents are licensed to you by owners. Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.
Some packages did not declare an SPDX license. Check the ``copyright`` file for each package for more information about their licensing.
"@

$output = Run-VcpkgAndCaptureOutput @commonArgs license-report "--x-builtin-ports-root=$PSScriptRoot/../e2e-ports"
Throw-IfFailed
Throw-IfNonEqual -Actual $output -Expected @"
Installed contents are licensed to you by owners. Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.
Some packages did not declare an SPDX license. Check the ``copyright`` file for each package for more information about their licensing.
Installed packages declare the following licenses:
BSD-3-Clause
MIT

"@

# Installing another port that says BSD-3-clause like bsd-on-mit results in no change to the license report
Run-Vcpkg @commonArgs remove "--x-builtin-ports-root=$PSScriptRoot/../e2e-ports" vcpkg-license-bsd
Throw-IfFailed

$output = Run-VcpkgAndCaptureOutput @commonArgs license-report "--x-builtin-ports-root=$PSScriptRoot/../e2e-ports"
Throw-IfFailed
Throw-IfNonEqual -Actual $output -Expected @"
Installed contents are licensed to you by owners. Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.
Some packages did not declare an SPDX license. Check the ``copyright`` file for each package for more information about their licensing.
Installed packages declare the following licenses:
BSD-3-Clause
MIT

"@

Run-Vcpkg @commonArgs remove "--x-builtin-ports-root=$PSScriptRoot/../e2e-ports" vcpkg-license-bsd-on-mit vcpkg-license-mit
Throw-IfFailed

# Only unknown from vcpkg-empty-port left
$output = Run-VcpkgAndCaptureOutput @commonArgs license-report "--x-builtin-ports-root=$PSScriptRoot/../e2e-ports"
Throw-IfFailed
Throw-IfNonEqual -Actual $output -Expected @"
Installed contents are licensed to you by owners. Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.
Some packages did not declare an SPDX license. Check the ``copyright`` file for each package for more information about their licensing.

"@

Run-Vcpkg @commonArgs remove vcpkg-empty-port
Throw-IfFailed

# Test that license ANDed together are broken onto separate lines
$output = Run-VcpkgAndCaptureOutput @commonArgs install "--x-builtin-ports-root=$PSScriptRoot/../e2e-ports" vcpkg-license-apache-and-boost
Throw-IfFailed
Throw-IfNonContains -Actual $output -Expected @"
Installed contents are licensed to you by owners. Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.
Packages installed in this vcpkg installation declare the following licenses:
Apache-2.0
BSL-1.0

"@

$output = Run-VcpkgAndCaptureOutput @commonArgs license-report "--x-builtin-ports-root=$PSScriptRoot/../e2e-ports"
Throw-IfFailed
Throw-IfNonEqual -Actual $output -Expected @"
Installed contents are licensed to you by owners. Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.
Installed packages declare the following licenses:
Apache-2.0
BSL-1.0

"@

Run-Vcpkg @commonArgs remove vcpkg-license-apache-and-boost
Throw-IfFailed

# Test that license reporting responds to features

# Install without specifying features (should behave like empty port)
$output = Run-VcpkgAndCaptureOutput @commonArgs install "--x-builtin-ports-root=$PSScriptRoot/../e2e-ports" vcpkg-license-features
Throw-IfFailed
Throw-IfNonContains -Actual $output -Expected @"
Some packages did not declare an SPDX license. Check the ``copyright`` file for each package for more information about their licensing.
"@

$output = Run-VcpkgAndCaptureOutput @commonArgs license-report "--x-builtin-ports-root=$PSScriptRoot/../e2e-ports"
Throw-IfFailed
Throw-IfNonEqual -Actual $output -Expected @"
Installed contents are licensed to you by owners. Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.
Some packages did not declare an SPDX license. Check the ``copyright`` file for each package for more information about their licensing.

"@

# Install apache-2 and boost features
Run-Vcpkg @commonArgs remove vcpkg-license-features
$output = Run-VcpkgAndCaptureOutput @commonArgs install "--x-builtin-ports-root=$PSScriptRoot/../e2e-ports" "vcpkg-license-features[apache-2,boost]"
Throw-IfFailed

$output = Run-VcpkgAndCaptureOutput @commonArgs license-report "--x-builtin-ports-root=$PSScriptRoot/../e2e-ports"
Throw-IfFailed
Throw-IfContains -Actual $output -Expected @"
Some packages did not declare an SPDX license. Check the ``copyright`` file for each package for more information about their licensing.
"@
Throw-IfNonContains -Actual $output -Expected @"
Installed contents are licensed to you by owners. Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.
Installed packages declare the following licenses:
Apache-2.0
BSL-1.0

"@

# Install bsd-3-clause, mit, and null features (null should trigger warning)
Run-Vcpkg @commonArgs remove vcpkg-license-features
$output = Run-VcpkgAndCaptureOutput @commonArgs install "--x-builtin-ports-root=$PSScriptRoot/../e2e-ports" "vcpkg-license-features[bsd-3-clause,mit,null]"
Throw-IfFailed
Throw-IfNonContains -Actual $output -Expected @"
Installed contents are licensed to you by owners. Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.
Some packages did not declare an SPDX license. Check the ``copyright`` file for each package for more information about their licensing.
Packages installed in this vcpkg installation declare the following licenses:
BSD-3-Clause
MIT

"@

$output = Run-VcpkgAndCaptureOutput @commonArgs license-report "--x-builtin-ports-root=$PSScriptRoot/../e2e-ports"
Throw-IfFailed
Throw-IfNonContains -Actual $output -Expected @"
Installed contents are licensed to you by owners. Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.
Some packages did not declare an SPDX license. Check the ``copyright`` file for each package for more information about their licensing.
Installed packages declare the following licenses:
BSD-3-Clause
MIT

"@

Run-Vcpkg @commonArgs remove vcpkg-license-features
Throw-IfFailed
1 change: 1 addition & 0 deletions include/vcpkg/base/contractual-constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ namespace vcpkg
inline constexpr StringLiteral SpdxGenerates = "GENERATES";
inline constexpr StringLiteral SpdxLicenseConcluded = "licenseConcluded";
inline constexpr StringLiteral SpdxLicenseDeclared = "licenseDeclared";
inline constexpr StringLiteral SpdxLicenseRefVcpkgNull = "LicenseRef-vcpkg-null";
inline constexpr StringLiteral SpdxNoAssertion = "NOASSERTION";
inline constexpr StringLiteral SpdxNone = "NONE";
inline constexpr StringLiteral SpdxPackageFileName = "packageFileName";
Expand Down
22 changes: 21 additions & 1 deletion include/vcpkg/base/message-data.inc.h
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,7 @@ DECLARE_MESSAGE(CmdInstallExample1,
"This is a command line, only the <> parts should be localized",
"vcpkg install <port name> <port name>...")
DECLARE_MESSAGE(CmdIntegrateSynopsis, (), "", "Integrates vcpkg with machines, projects, or shells")
DECLARE_MESSAGE(CmdLicenseReportSynopsis, (), "", "Displays the declared licenses of all ports in the installed tree")
DECLARE_MESSAGE(CmdListExample2,
(),
"This is a command line, only the <filter> part should be localized",
Expand Down Expand Up @@ -2088,7 +2089,6 @@ DECLARE_MESSAGE(LicenseExpressionExpectLicenseFoundCompound,
"Example of {value} is 'AND'",
"Expected a license name, found the compound {value}.")
DECLARE_MESSAGE(LicenseExpressionExpectLicenseFoundEof, (), "", "Expected a license name, found the end of the string.")
DECLARE_MESSAGE(LicenseExpressionExpectLicenseFoundParen, (), "", "Expected a license name, found a parenthesis.")
DECLARE_MESSAGE(LicenseExpressionImbalancedParens,
(),
"",
Expand Down Expand Up @@ -2219,6 +2219,11 @@ DECLARE_MESSAGE(NoInstalledPackages,
(),
"The name 'search' is the name of a command that is not localized.",
"No packages are installed. Did you mean `search`?")
DECLARE_MESSAGE(NoInstalledPackagesLicenseReport,
(),
"",
"There are no installed packages, and thus no licenses of installed packages. Did you mean to install "
"something first?")
DECLARE_MESSAGE(NonExactlyArgs,
(msg::command_name, msg::expected, msg::actual),
"{expected} and {actual} are integers",
Expand Down Expand Up @@ -2291,6 +2296,21 @@ DECLARE_MESSAGE(OverwritingFile, (msg::path), "", "File {path} was already prese
DECLARE_MESSAGE(PackageAbi, (msg::spec, msg::package_abi), "", "{spec} package ABI: {package_abi}")
DECLARE_MESSAGE(PackageAlreadyRemoved, (msg::spec), "", "unable to remove {spec}: already removed")
DECLARE_MESSAGE(PackageDiscoveryHeader, (), "", "Package Discovery")
DECLARE_MESSAGE(PackageLicenseSpdx, (), "", "Installed packages declare the following licenses:")
DECLARE_MESSAGE(PackageLicenseSpdxThisInstall,
(),
"",
"Packages installed in this vcpkg installation declare the following licenses:")
DECLARE_MESSAGE(PackageLicenseUnknown,
(),
"",
"Some packages did not declare an SPDX license. Check the `copyright` file for each package for more "
"information about their licensing.")
DECLARE_MESSAGE(PackageLicenseWarning,
(),
"",
"Installed contents are licensed to you by owners. Microsoft is not responsible for, nor does it grant "
"any licenses to, third-party packages.")
DECLARE_MESSAGE(PackageManipulationHeader, (), "", "Package Manipulation")
DECLARE_MESSAGE(PackageInfoHelp, (), "", "Display detailed information on packages")
DECLARE_MESSAGE(PackageFailedtWhileExtracting,
Expand Down
1 change: 1 addition & 0 deletions include/vcpkg/base/parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace vcpkg

struct ParseMessages
{
void print_errors_or_warnings() const;
void exit_if_errors_or_warnings() const;
bool good() const noexcept { return m_good; }
bool any_errors() const noexcept { return m_error_count != 0; }
Expand Down
8 changes: 8 additions & 0 deletions include/vcpkg/commands.install.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,18 @@ namespace vcpkg
PackageSpec m_spec;
};

struct LicenseReport
{
bool any_unknown_licenses = false;
std::set<std::string> named_licenses;
void print_license_report(const msg::MessageT<>& named_license_heading) const;
};

struct InstallSummary
{
std::vector<SpecSummary> results;
ElapsedTime elapsed;
LicenseReport license_report;
bool failed = false;

LocalizedString format_results() const;
Expand Down
10 changes: 10 additions & 0 deletions include/vcpkg/commands.license-report.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

#include <vcpkg/fwd/vcpkgcmdarguments.h>
#include <vcpkg/fwd/vcpkgpaths.h>

namespace vcpkg
{
extern const CommandMetadata CommandLicenseReportMetadata;
void command_license_report_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
}
Loading
Loading