Skip to content

Add -SkipDependencyCheck to cmdlets. #550

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 3 commits into from
Nov 29, 2021
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
13 changes: 10 additions & 3 deletions src/code/InstallHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ public void InstallPackages(
string specifiedPath,
bool asNupkg,
bool includeXML,
bool skipDependencyCheck,
List<string> pathsToInstallPkg)
{
_cmdletPassedIn.WriteVerbose(string.Format("Parameters passed in >>> Name: '{0}'; Version: '{1}'; Prerelease: '{2}'; Repository: '{3}'; " +
Expand Down Expand Up @@ -123,7 +124,12 @@ public void InstallPackages(
}

// Go through the repositories and see which is the first repository to have the pkg version available
ProcessRepositories(names, repository, _trustRepository, _credential);
ProcessRepositories(
packageNames: names,
repository: repository,
trustRepository: _trustRepository,
credential: _credential,
skipDependencyCheck: skipDependencyCheck);
}

#endregion
Expand All @@ -135,7 +141,8 @@ private void ProcessRepositories(
string[] packageNames,
string[] repository,
bool trustRepository,
PSCredential credential)
PSCredential credential,
bool skipDependencyCheck)
{
var listOfRepositories = RepositorySettings.Read(repository, out string[] _);
List<string> pckgNamesToInstall = packageNames.ToList();
Expand Down Expand Up @@ -185,7 +192,7 @@ private void ProcessRepositories(
tag: null,
repository: new string[] { repoName },
credential: credential,
includeDependencies: true);
includeDependencies: !skipDependencyCheck);

if (!pkgsFromRepoToInstall.Any())
{
Expand Down
9 changes: 8 additions & 1 deletion src/code/InstallPSResource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ namespace Microsoft.PowerShell.PowerShellGet.Cmdlets
/// The Install-PSResource cmdlet installs a resource.
/// It returns nothing.
/// </summary>

[Cmdlet(VerbsLifecycle.Install, "PSResource", DefaultParameterSetName = "NameParameterSet", SupportsShouldProcess = true)]
public sealed
class InstallPSResource : PSCmdlet
Expand Down Expand Up @@ -106,6 +105,13 @@ class InstallPSResource : PSCmdlet
[ValidateNotNullOrEmpty]
public PSResourceInfo InputObject { get; set; }

/// <summary>
/// Skips the check for resource dependencies, so that only found resources are installed,
/// and not any resources the found resource depends on.
/// </summary>
[Parameter]
public SwitchParameter SkipDependencyCheck { get; set; }

#endregion

#region Members
Expand Down Expand Up @@ -250,6 +256,7 @@ private void ProcessInstallHelper(string[] pkgNames, bool pkgPrerelease, string[
specifiedPath: null,
asNupkg: false,
includeXML: true,
skipDependencyCheck: SkipDependencyCheck,
pathsToInstallPkg: _pathsToInstallPkg);
}

Expand Down
10 changes: 9 additions & 1 deletion src/code/SavePSResource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,13 @@ public string Path
[ValidateNotNullOrEmpty]
public PSResourceInfo InputObject { get; set; }

/// <summary>
/// Skips the check for resource dependencies, so that only found resources are saved,
/// and not any resources the found resource depends on.
/// </summary>
[Parameter]
public SwitchParameter SkipDependencyCheck { get; set; }

#endregion

#region Method overrides
Expand Down Expand Up @@ -243,7 +250,8 @@ private void ProcessSaveHelper(string[] pkgNames, bool pkgPrerelease, string[] p
noClobber: false,
specifiedPath: _path,
asNupkg: false,
includeXML: false,
includeXML: false,
skipDependencyCheck: SkipDependencyCheck,
pathsToInstallPkg: new List<string> { _path } );
}

Expand Down
36 changes: 20 additions & 16 deletions src/code/UninstallPSResource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ public sealed class UninstallPSResource : PSCmdlet
public PSResourceInfo InputObject { get; set; }

/// <summary>
/// Skips check to see if other resources are dependent on the resource being uninstalled.
/// </summary>
[Parameter(ParameterSetName = NameParameterSet)]
[Parameter(ParameterSetName = InputObjectParameterSet)]
public SwitchParameter Force { get; set; }
[Parameter]
public SwitchParameter SkipDependencyCheck { get; set; }

#endregion

Expand Down Expand Up @@ -212,9 +212,9 @@ private bool UninstallModuleHelper(string pkgPath, string pkgName, out ErrorReco
errRecord = null;
var successfullyUninstalledPkg = false;

// if -Force is not specified and the pkg is a dependency for another package,
// if -SkipDependencyCheck is not specified and the pkg is a dependency for another package,
// an error will be written and we return false
if (!Force && CheckIfDependency(pkgName, out errRecord))
if (!SkipDependencyCheck && CheckIfDependency(pkgName, out errRecord))
{
return false;
}
Expand Down Expand Up @@ -301,9 +301,8 @@ private bool UninstallScriptHelper(string pkgPath, string pkgName, out ErrorReco
return successfullyUninstalledPkg;
}

private bool CheckIfDependency(string pkgName, out ErrorRecord errRecord)
private bool CheckIfDependency(string pkgName, out ErrorRecord errorRecord)
{
errRecord = null;
// this is a primitive implementation
// TODO: implement a dependencies database for querying dependency info
// cannot uninstall a module if another module is dependent on it
Expand All @@ -317,29 +316,34 @@ private bool CheckIfDependency(string pkgName, out ErrorRecord errRecord)
// RequiredModules is collection of PSModuleInfo objects that need to be iterated through to see if any of them are the pkg we're trying to uninstall
// If we anything from the final call gets returned, there is a dependency on this pkg.
IEnumerable<PSObject> pkgsWithRequiredModules = new List<PSObject>();
errorRecord = null;
try
{
pkgsWithRequiredModules = results.Where(
p => ((ReadOnlyCollection<PSModuleInfo>)p.Properties["RequiredModules"].Value).Where(
pkg => ((ReadOnlyCollection<PSModuleInfo>)pkg.Properties["RequiredModules"].Value).Where(
rm => rm.Name.Equals(pkgName, StringComparison.InvariantCultureIgnoreCase)).Any());
}
catch (Exception e)
{
var exMessage = String.Format("Error checking if resource is a dependency: {0}. If you would still like to uninstall, rerun the command with -Force", e.Message);
var ex = new ArgumentException(exMessage);
var DependencyCheckError = new ErrorRecord(ex, "DependencyCheckError", ErrorCategory.OperationStopped, null);
errRecord = DependencyCheckError;
errorRecord = new ErrorRecord(
new PSInvalidOperationException(
$"Error checking if resource is a dependency: {e.Message}."),
"UninstallPSResourceDependencyCheckError",
ErrorCategory.InvalidOperation,
null);
}

if (pkgsWithRequiredModules.Any())
{
var uniquePkgNames = pkgsWithRequiredModules.Select(p => p.Properties["Name"].Value).Distinct().ToArray();
var strUniquePkgNames = string.Join(",", uniquePkgNames);

var exMessage = String.Format("Cannot uninstall '{0}', the following package(s) take a dependency on this package: {1}. If you would still like to uninstall, rerun the command with -Force", pkgName, strUniquePkgNames);
var ex = new ArgumentException(exMessage);
var PackageIsaDependency = new ErrorRecord(ex, "PackageIsaDependency", ErrorCategory.OperationStopped, null);
errRecord = PackageIsaDependency;
errorRecord = new ErrorRecord(
new PSInvalidOperationException(
$"Cannot uninstall '{pkgName}'. The following package(s) take a dependency on this package: {strUniquePkgNames}. If you would still like to uninstall, rerun the command with -SkipDependencyCheck"),
"UninstallPSResourcePackageIsaDependency",
ErrorCategory.InvalidOperation,
null);

return true;
}
Expand Down
10 changes: 9 additions & 1 deletion src/code/UpdatePSResource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,13 @@ public sealed class UpdatePSResource : PSCmdlet
[Parameter]
public SwitchParameter Force { get; set; }

/// <summary>
/// Skips the check for resource dependencies, so that only found resources are updated,
/// and not any resources the found resource depends on.
/// </summary>
[Parameter]
public SwitchParameter SkipDependencyCheck { get; set; }

#endregion

#region Override Methods
Expand Down Expand Up @@ -166,6 +173,7 @@ protected override void ProcessRecord()
specifiedPath: null,
asNupkg: false,
includeXML: true,
skipDependencyCheck: SkipDependencyCheck,
pathsToInstallPkg: _pathsToInstallPkg);
}

Expand Down Expand Up @@ -253,7 +261,7 @@ private string[] ProcessPackageNames(
tag: null,
repository: Repository,
credential: Credential,
includeDependencies: false))
includeDependencies: !SkipDependencyCheck))
{
if (!repositoryPackages.ContainsKey(foundResource.Name))
{
Expand Down
21 changes: 16 additions & 5 deletions test/InstallPSResource.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Describe 'Test Install-PSResource for Module' {
AfterEach {
Uninstall-PSResource "TestModule", "TestModule99", "myTestModule", "myTestModule2", "testModulePrerelease",
"testModuleWithlicense","PSGetTestModule", "PSGetTestDependency1", "TestFindModule","ClobberTestModule1",
"ClobberTestModule2" -Force -ErrorAction SilentlyContinue
"ClobberTestModule2" -SkipDependencyCheck -ErrorAction SilentlyContinue
}

AfterAll {
Expand Down Expand Up @@ -103,22 +103,22 @@ Describe 'Test Install-PSResource for Module' {
}

It "Install resource when given Name, Version '*', should install the latest version" {
$pkg = Install-PSResource -Name "TestModule" -Version "*" -Repository $TestGalleryName
Install-PSResource -Name "TestModule" -Version "*" -Repository $TestGalleryName
$pkg = Get-Module "TestModule" -ListAvailable
$pkg.Name | Should -Be "TestModule"
$pkg.Version | Should -Be "1.3.0"
}

It "Install resource with latest (including prerelease) version given Prerelease parameter" {
$pkg = Install-PSResource -Name "TestModulePrerelease" -Prerelease -Repository $TestGalleryName
Install-PSResource -Name "TestModulePrerelease" -Prerelease -Repository $TestGalleryName
$pkg = Get-Module "TestModulePrerelease" -ListAvailable
$pkg.Name | Should -Be "TestModulePrerelease"
$pkg.Version | Should -Be "0.0.1"
$pkg.PrivateData.PSData.Prerelease | Should -Be "preview"
}

It "Install a module with a dependency" {
$pkg = Install-PSResource -Name "PSGetTestModule" -Prerelease -Repository $TestGalleryName
Install-PSResource -Name "PSGetTestModule" -Prerelease -Repository $TestGalleryName
$pkg = Get-Module "PSGetTestModule" -ListAvailable
$pkg.Name | Should -Be "PSGetTestModule"
$pkg.Version | Should -Be "2.0.2"
Expand All @@ -129,6 +129,17 @@ Describe 'Test Install-PSResource for Module' {
$pkg.Version | Should -Be "1.0.0"
}

It "Install a module with a dependency and skip installing the dependency" {
Install-PSResource -Name "PSGetTestModule" -Prerelease -Repository $TestGalleryName -SkipDependencyCheck
$pkg = Get-Module "PSGetTestModule" -ListAvailable
$pkg.Name | Should -Be "PSGetTestModule"
$pkg.Version | Should -Be "2.0.2"
$pkg.PrivateData.PSData.Prerelease | Should -Be "-alpha1"

$pkg = Get-Module "PSGetTestDependency1" -ListAvailable
$pkg | Should -BeNullOrEmpty
}

It "Install resource via InputObject by piping from Find-PSresource" {
Find-PSResource -Name "TestModule" -Repository $TestGalleryName | Install-PSResource
$pkg = Get-Module "TestModule" -ListAvailable
Expand Down Expand Up @@ -309,7 +320,7 @@ Describe 'Test Install-PSResource for interactive and root user scenarios' {
}

AfterEach {
Uninstall-PSResource "TestModule", "testModuleWithlicense" -Force -ErrorAction SilentlyContinue
Uninstall-PSResource "TestModule", "testModuleWithlicense" -SkipDependencyCheck -ErrorAction SilentlyContinue
}

AfterAll {
Expand Down
7 changes: 7 additions & 0 deletions test/SavePSResource.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,13 @@ Describe 'Test Save-PSResource for PSResources' {
(Get-ChildItem $pkgDirs[1].FullName).Count | Should -Be 1
}

It "Save a module with a dependency and skip saving the dependency" {
Save-PSResource -Name "PSGetTestModule" -Prerelease -Repository $TestGalleryName -Path $SaveDir -SkipDependencyCheck
$pkgDirs = Get-ChildItem -Path $SaveDir | Where-Object { $_.Name -eq "PSGetTestModule" -or $_.Name -eq "PSGetTestDependency1" }
$pkgDirs.Count | Should -Be 1
(Get-ChildItem $pkgDirs[0].FullName).Count | Should -Be 1
}

It "Save resource via InputObject by piping from Find-PSresource" {
Find-PSResource -Name "TestModule" -Repository $TestGalleryName | Save-PSResource -Path $SaveDir
$pkgDir = Get-ChildItem -Path $SaveDir | Where-Object Name -eq "TestModule"
Expand Down
29 changes: 14 additions & 15 deletions test/UninstallPSResource.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Describe 'Test Uninstall-PSResource for Modules' {
$testModuleName = "test_module"
$testScriptName = "test_script"
Get-NewPSResourceRepositoryFile
$res = Uninstall-PSResource -name ContosoServer -Version "*"
Uninstall-PSResource -name ContosoServer -Version "*"
}
BeforeEach{
$null = Install-PSResource ContosoServer -Repository $TestGalleryName -TrustRepository -WarningAction SilentlyContinue
Expand All @@ -21,7 +21,7 @@ Describe 'Test Uninstall-PSResource for Modules' {
}

It "Uninstall a specific module by name" {
$res = Uninstall-PSResource -name ContosoServer
Uninstall-PSResource -name ContosoServer
Get-Module ContosoServer -ListAvailable | Should -Be $null
}

Expand All @@ -38,28 +38,28 @@ Describe 'Test Uninstall-PSResource for Modules' {
It "Uninstall a list of modules by name" {
$null = Install-PSResource BaseTestPackage -Repository $TestGalleryName -TrustRepository -WarningAction SilentlyContinue

$res = Uninstall-PSResource -Name BaseTestPackage, ContosoServer
Uninstall-PSResource -Name BaseTestPackage, ContosoServer
Get-Module ContosoServer, BaseTestPackage -ListAvailable | Should -be $null
}

It "Uninstall a specific script by name" {
$null = Install-PSResource Test-RPC -Repository $TestGalleryName -TrustRepository -WarningAction SilentlyContinue

$pkg = Uninstall-PSResource -name Test-RPC
Uninstall-PSResource -name Test-RPC
}

It "Uninstall a list of scripts by name" {
$null = Install-PSResource adsql, airoute -Repository $TestGalleryName -TrustRepository -WarningAction SilentlyContinue

$pkg = Uninstall-PSResource -Name adsql, airoute
Uninstall-PSResource -Name adsql, airoute
}

It "Uninstall a module when given name and specifying all versions" {
$null = Install-PSResource ContosoServer -Repository $TestGalleryName -Version "1.0.0" -TrustRepository -WarningAction SilentlyContinue
$null = Install-PSResource ContosoServer -Repository $TestGalleryName -Version "1.5.0" -TrustRepository -WarningAction SilentlyContinue
$null = Install-PSResource ContosoServer -Repository $TestGalleryName -Version "2.0.0" -TrustRepository -WarningAction SilentlyContinue

$res = Uninstall-PSResource -Name ContosoServer -version "*"
Uninstall-PSResource -Name ContosoServer -version "*"
$pkgs = Get-Module ContosoServer -ListAvailable
$pkgs.Version | Should -Not -Contain "1.0.0"
$pkgs.Version | Should -Not -Contain "1.5.0"
Expand All @@ -72,7 +72,7 @@ Describe 'Test Uninstall-PSResource for Modules' {
$null = Install-PSResource ContosoServer -Repository $TestGalleryName -Version "1.5.0" -TrustRepository -WarningAction SilentlyContinue
$null = Install-PSResource ContosoServer -Repository $TestGalleryName -Version "2.0.0" -TrustRepository -WarningAction SilentlyContinue

$res = Uninstall-PSResource -Name ContosoServer
Uninstall-PSResource -Name ContosoServer
$pkgs = Get-Module ContosoServer -ListAvailable
$pkgs.Version | Should -Not -Contain "1.0.0"
$pkgs.Version | Should -Not -Contain "1.5.0"
Expand All @@ -85,7 +85,7 @@ Describe 'Test Uninstall-PSResource for Modules' {
$null = Install-PSResource ContosoServer -Repository $TestGalleryName -Version "1.5.0" -TrustRepository -WarningAction SilentlyContinue
$null = Install-PSResource ContosoServer -Repository $TestGalleryName -Version "2.0.0" -TrustRepository -WarningAction SilentlyContinue

$res = Uninstall-PSResource -Name "ContosoServer" -Version "1.0.0"
Uninstall-PSResource -Name "ContosoServer" -Version "1.0.0"
$pkgs = Get-Module ContosoServer -ListAvailable
$pkgs.Version | Should -Not -Contain "1.0.0"
}
Expand All @@ -106,7 +106,7 @@ Describe 'Test Uninstall-PSResource for Modules' {
$null = Install-PSResource ContosoServer -Repository $TestGalleryName -Version "1.5.0" -TrustRepository -WarningAction SilentlyContinue
$null = Install-PSResource ContosoServer -Repository $TestGalleryName -Version "2.0.0" -TrustRepository -WarningAction SilentlyContinue

$res = Uninstall-PSResource -Name ContosoServer -Version $Version
Uninstall-PSResource -Name ContosoServer -Version $Version
$pkgs = Get-Module ContosoServer -ListAvailable
$pkgs.Version | Should -Not -Contain $Version
}
Expand Down Expand Up @@ -169,8 +169,7 @@ Describe 'Test Uninstall-PSResource for Modules' {
}

It "Uninstall module using -WhatIf, should not uninstall the module" {
$res = Uninstall-PSResource -Name "ContosoServer" -WhatIf

Uninstall-PSResource -Name "ContosoServer" -WhatIf
$pkg = Get-Module ContosoServer -ListAvailable
$pkg.Version | Should -Be "2.5"
}
Expand All @@ -183,16 +182,16 @@ Describe 'Test Uninstall-PSResource for Modules' {
$pkg = Get-Module "RequiredModule1" -ListAvailable
$pkg | Should -Not -Be $null

$ev | Should -Be "Cannot uninstall 'RequiredModule1', the following package(s) take a dependency on this package: test_module. If you would still like to uninstall, rerun the command with -Force"
$ev.FullyQualifiedErrorId | Should -BeExactly 'UninstallPSResourcePackageIsaDependency,Microsoft.PowerShell.PowerShellGet.Cmdlets.UninstallPSResource'
}

It "Uninstall module that is a dependency for another module using -Force" {
It "Uninstall module that is a dependency for another module using -SkipDependencyCheck" {
$null = Install-PSResource "test_module" -Repository $TestGalleryName -TrustRepository -WarningAction SilentlyContinue

$res = Uninstall-PSResource -Name "RequiredModule1" -Force
Uninstall-PSResource -Name "RequiredModule1" -SkipDependencyCheck

$pkg = Get-Module "RequiredModule1" -ListAvailable
$pkg | Should -Be $null
$pkg | Should -BeNullOrEmpty
}

It "Uninstall PSResourceInfo object piped in" {
Expand Down