diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 00000000..3f54a1ce --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,97 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Build and Import Module", + "command": "pwsh", + "type": "shell", + "windows": { + "command": "c:\\windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe" + }, + "args": [ + "-command", + "Import-Module ${workspaceFolder}\\tools\\build.psm1;", + "Install-DevelopmentModule", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": true + }, + "presentation": { + "echo": true, + "reveal": "always", + "focus": true, + "panel": "shared", + "showReuseMessage": true, + "clear": false, + } + }, + { + "label": "Install Dependencies", + "command": "pwsh", + "windows": { + "command": "c:\\windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe" + }, + "args": [ + "-command", + "Import-Module ${workspaceFolder}\\tools\\build.psm1;", + "Install-Dependencies" + ], + "problemMatcher": [], + "presentation": { + "echo": true, + "reveal": "always", + "focus": true, + "panel": "shared", + "showReuseMessage": true, + "clear": false, + } + }, + { + "label": "Remove Development Module", + "command": "pwsh", + "windows": { + "command": "c:\\windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe" + }, + "args": [ + "-command", + "Import-Module ${workspaceFolder}\\tools\\build.psm1;", + "Uninstall-DevelopmentModule" + ], + "problemMatcher": [], + "presentation": { + "echo": true, + "reveal": "always", + "focus": true, + "panel": "shared", + "showReuseMessage": true, + "clear": false, + } + }, + { + "label": "Run Full Test Suite", + "command": "pwsh", + "windows": { + "command": "c:\\windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe" + }, + "args": [ + "-command", + "Import-Module ${workspaceFolder}\\tools\\build.psm1;", + "Install-Dependencies;", + "Invoke-PowerShellGetTest" + ], + "problemMatcher": [], + "presentation": { + "echo": true, + "reveal": "always", + "focus": true, + "panel": "shared", + "showReuseMessage": true, + "clear": false, + } + } + ] +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 65031e2d..60be57c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,31 @@ # Changelog +## 2.1.4 + +Bug Fix + +- Fixed hang when publishing some modules (#478) + +## 2.1.3 + +New Features + +- Added -Scope parameter to Update-Module (Thanks @lwajswaj!) (#471) +- Added -Exclude parameter to Publish-Module (Thanks @Benny1007!) (#191) +- Added -SkipAutomticTags parameter to Publish-Module (Thanks @awickham10!) (#452) + +Bug Fix + +- Fixed issue with finding modules using macOS and .NET Core 3.0 + ## 2.1.2 New Feature -- Added support for registering repositories with special characters +- Added support for registering repositories with special characters (@Thanks jborean93!) (#442) ## 2.1.1 + - Fix DSC resource folder structure ## 2.1.0 diff --git a/DSC/DSCResources/MSFT_PSModule/en-US/MSFT_PSModule.strings.psd1 b/DSC/DSCResources/MSFT_PSModule/en-US/MSFT_PSModule.strings.psd1 index c43e7661..971bf06d 100644 --- a/DSC/DSCResources/MSFT_PSModule/en-US/MSFT_PSModule.strings.psd1 +++ b/DSC/DSCResources/MSFT_PSModule/en-US/MSFT_PSModule.strings.psd1 @@ -25,12 +25,11 @@ ConvertFrom-StringData -StringData @' StartUnInstallModule = Begin invoking Remove-Item to remove the module '{0}' from the file system. InstalledSuccess = Successfully installed the module '{0}' UnInstalledSuccess = Successfully uninstalled the module '{0}' - VersionMismatch = The installed Module '{0}' has the version: '{1}' - RepositoryMismatch = The installed Module '{0}' is from '{1}' repository. + VersionMismatch = The installed module '{0}' has the version: '{1}' + RepositoryMismatch = The installed module '{0}' is from the '{1}' repository. FoundModulePath = Found the module path: '{0}'. - MultipleModuleFound = Total: '{0}' modules found with the same name. Please use -RequiredVersion for filtering. Message: {1} - InstallationPolicyWarning = You are installing the module '{0}' from an untrusted repository' {1}'. Your current InstallationPolicy is '{2}'. If you trust the repository, set the policy to "Trusted". - InstallationPolicyFailed = Failed in the installation policy. Your current InstallationPolicy is '{0}' and the repository is '{1}'. If you trust the repository, set the policy to "Trusted". + InstallationPolicyWarning = The module '{0}' was installed from the untrusted repository' {1}'. The InstallationPolicy is set to '{2}' to override the repository installation policy. If you trust the repository, set the repository installation policy to 'Trusted', that will also remove this warning. + InstallationPolicyFailed = The current installation policy do not allow installation from this repository. Your current installation policy is '{0}' and the repository installation policy is '{1}'. If you trust the repository, either change the repository installation policy, or set the parameter InstallationPolicy to 'Trusted' to override the repository installation policy. GetTargetResourceMessage = Getting the current state of the module '{0}'. TestTargetResourceMessage = Determining if the module '{0}' is in the desired state. '@ diff --git a/README.md b/README.md index 0f945216..72914752 100644 --- a/README.md +++ b/README.md @@ -106,29 +106,49 @@ Import-Module src/PowerShellGet ``` +Local Development +================= +### Visual Studio Code:- +1. Open VSCode choosing "Run as Administrator" +2. Select Terminal>Run Task>Install Dependencies +3. Select Terminal>Run Task>Build and Import Module + +for subsequent changes you can just run 'Build and Import Module' or press ctrl + shift + B + +### Standard PowerShell:- +1. Open an administrative PowerShell prompt +2. Run the following commands +```PowerShell +Import-Module "$ClonePath\tools\build.psm1" +Install-Dependencies +Install-DevelopmentModule +``` + +This will take the published module from ./dist and install it into the powershell module path under the current version of PowerShellGet apending 9999 to the version number. + +An explicit or implicit (such as when the test suite is invoked) import of the PowerShell get module will ensure the module version under development gets loaded. + +It is therefore easy to see with ```Get Module``` that the version under development is loaded, like this:- + +![alt text](./imgs/readme-getmodule-1.png "") + +To remove this module and revert to the production PowerShellGallery published version, simply remove the folder from the module path. (if running VSCode select Terminal>Run Task>Remove Development Module). + Running Tests ============= +### VSCode +You can run the test task Terminal>Run Task>Run Full Test Suite + +### Non VSCode + Pester-based PowerShellGet Tests are located in `/PowerShellGet/Tests` folder. Run following commands in PowerShell Console with Administrator privileges. ```powershell Import-Module "$ClonePath\tools\build.psm1" - Install-Dependencies - -# Option 1: Execute the following, replacing $ClonePath, when testing PowerShellGet module changes under $ClonePath. -# $env:PSModulePath = "$ClonePath\src;$env:PSModulePath" - -# Option 2: Execute the following commands to run tests with the merged PSModule.psm1 -<# -Update-ModuleManifestFunctions -Publish-ModuleArtifacts -Install-PublishedModule -#> - -# Run tests Invoke-PowerShellGetTest ``` diff --git a/SignConfig.xml b/SignConfig.xml index 071e8b31..cce952dc 100644 --- a/SignConfig.xml +++ b/SignConfig.xml @@ -21,4 +21,4 @@ - \ No newline at end of file + diff --git a/Tests/PSGetPublishModule.Tests.ps1 b/Tests/PSGetPublishModule.Tests.ps1 index c62a12cb..592ca25e 100644 --- a/Tests/PSGetPublishModule.Tests.ps1 +++ b/Tests/PSGetPublishModule.Tests.ps1 @@ -134,7 +134,7 @@ Describe PowerShell.PSGet.PublishModuleTests -Tags 'BVT','InnerLoop' { # # Expected Result: should be able to publish a module # - It PublishModuleWithNameForSxSVersion { + It "PublishModuleWithNameForSxSVersion" { $version = "2.0.0.0" $semanticVersion = '2.0.0' RemoveItem "$script:PublishModuleBase\*" @@ -763,6 +763,83 @@ Describe PowerShell.PSGet.PublishModuleTests -Tags 'BVT','InnerLoop' { } ` -Skip:$($PSVersionTable.PSVersion -lt '5.0.0') + # Purpose: Test Publish-Module cmdlet warns when tag length is greater than 4000 + # + # Action: Create a module manifest with PrivateData\PSData hashtable, try to publish + # + # Expected Result: Publish operation should succeed and should have warned about tag length. + # + It PublishModuleFunctionsAsTagsWarnWithoutSkipAutomaticTags { + $version = "1.0.0" + $Description = "$script:PublishModuleName module" + $Tags = "PSGet","DSC" + $Author = "AuthorName" + $CompanyName = "CompanyName" + $CopyRight = "CopyRight" + + $functionNames = 1..250 | Foreach-Object { "Get-TestFunction$($_)" } + $tempFunctions = 1..250 | Foreach-Object { "function Get-TestFunction$($_) { Get-Date }" + [Environment]::NewLine } + Set-Content (Join-Path -Path $script:PublishModuleBase -ChildPath "$script:PublishModuleName.psm1") -Value $tempFunctions + + New-ModuleManifest -Path (Join-Path -Path $script:PublishModuleBase -ChildPath "$script:PublishModuleName.psd1") ` + -ModuleVersion $version ` + -Description "$script:PublishModuleName module" ` + -NestedModules "$script:PublishModuleName.psm1" ` + -Author $Author ` + -CompanyName $CompanyName ` + -Copyright $CopyRight ` + -Tags $Tags ` + -FunctionsToExport $functionNames + + Publish-Module -Path $script:PublishModuleBase ` + -NuGetApiKey $script:ApiKey ` + -Repository "PSGallery" ` + -WarningAction SilentlyContinue ` + -WarningVariable wa + + Assert ("$wa".Contains('4000 characters')) "Warning messages should include 'Tag list exceeded 4000 characters and may not be accepted by some Nuget feeds.'" + } ` + -Skip:$($PSVersionTable.PSVersion -lt '5.0.0') + + # Purpose: Test Publish-Module cmdlet excludes functions from tags when using SkipAutomaticTags parameter + # + # Action: Create a module manifest with PrivateData\PSData hashtable, try to publish with SkipAutomaticTags parameter + # + # Expected Result: Publish operation should succeed and should not have warned about tag length + # + It PublishModuleFunctionsAsTagsWithSkipAutomaticTags { + $version = "1.0.0" + $Description = "$script:PublishModuleName module" + $Tags = "PSGet","DSC" + $Author = "AuthorName" + $CompanyName = "CompanyName" + $CopyRight = "CopyRight" + + $functionNames = 1..250 | Foreach-Object { "Get-TestFunction$($_)" } + $tempFunctions = 1..250 | Foreach-Object { "function Get-TestFunction$($_) { Get-Date }" + [Environment]::NewLine } + Set-Content (Join-Path -Path $script:PublishModuleBase -ChildPath "$script:PublishModuleName.psm1") -Value $tempFunctions + + New-ModuleManifest -Path (Join-Path -Path $script:PublishModuleBase -ChildPath "$script:PublishModuleName.psd1") ` + -ModuleVersion $version ` + -Description "$script:PublishModuleName module" ` + -NestedModules "$script:PublishModuleName.psm1" ` + -Author $Author ` + -CompanyName $CompanyName ` + -Copyright $CopyRight ` + -Tags $Tags ` + -FunctionsToExport $functionNames + + Publish-Module -Path $script:PublishModuleBase ` + -NuGetApiKey $script:ApiKey ` + -Repository "PSGallery" ` + -SkipAutomaticTags ` + -WarningAction SilentlyContinue ` + -WarningVariable wa + + Assert (-not "$wa".Contains('4000 characters')) "Warning messages should not include 'Tag list exceeded 4000 characters and may not be accepted by some Nuget feeds.'" + } ` + -Skip:$($PSVersionTable.PSVersion -lt '5.0.0') + # Purpose: Test Publish-Module cmdlet gets the PSData properties from the module manifest file and also with Uri objects specified to the cmdlet # # Action: Create a module manifest with PrivateData\PSData hashtable, try to publish it with Uri objects to ProjectUri, IconUri and LicenseUri parameters @@ -1176,7 +1253,7 @@ Describe PowerShell.PSGet.PublishModuleTests -Tags 'BVT','InnerLoop' { finally { Install-NuGetBinaries } - } -Skip:$($PSEdition -eq 'Core') + } -Skip:$($PSEdition -eq 'Core' -or $env:APPVEYOR_TEST_PASS -eq 'True') # Purpose: Validate that Publish-Module prompts to install NuGet.exe if NuGet.exe file is not found # @@ -1234,7 +1311,7 @@ Describe PowerShell.PSGet.PublishModuleTests -Tags 'BVT','InnerLoop' { finally { Install-NuGetBinaries } - } -Skip:$($PSEdition -eq 'Core') + } -Skip:$($PSEdition -eq 'Core' -or $env:APPVEYOR_TEST_PASS -eq 'True') # Purpose: Validate that Publish-Module prompts to upgrade NuGet.exe if local NuGet.exe file is less than minimum required version # @@ -1300,7 +1377,7 @@ Describe PowerShell.PSGet.PublishModuleTests -Tags 'BVT','InnerLoop' { finally { Install-NuGetBinaries } - } -Skip:$($PSEdition -eq 'Core') + } -Skip:$($PSEdition -eq 'Core' -or $env:APPVEYOR_TEST_PASS -eq 'True') # Purpose: Validate that Publish-Module prompts to install NuGet.exe if file not found # @@ -1357,7 +1434,7 @@ Describe PowerShell.PSGet.PublishModuleTests -Tags 'BVT','InnerLoop' { finally { Install-NuGetBinaries } - } -Skip:$($PSEdition -eq 'Core') + } -Skip:$($PSEdition -eq 'Core' -or $env:APPVEYOR_TEST_PASS -eq 'True') } Describe PowerShell.PSGet.PublishModuleTests.P1 -Tags 'P1','OuterLoop' { diff --git a/Tests/PSGetRequireLicenseAcceptance.Tests.ps1 b/Tests/PSGetRequireLicenseAcceptance.Tests.ps1 index fe6c2330..d081d656 100644 --- a/Tests/PSGetRequireLicenseAcceptance.Tests.ps1 +++ b/Tests/PSGetRequireLicenseAcceptance.Tests.ps1 @@ -7,7 +7,7 @@ <# Name: PowerShell.PSGet.PSGetRequireLicenseAcceptance - Description: Tests for Require License Acceptance functionality + Description: Tests for Require License Acceptance functionality #> function SuiteSetup { @@ -18,7 +18,7 @@ function SuiteSetup { $script:MyDocumentsModulesPath = Get-CurrentUserModulesPath $script:PSGetLocalAppDataPath = Get-PSGetLocalAppDataPath $script:TempPath = Get-TempPath - $script:PSGetRequireLicenseAcceptanceFormatVersion = "2.0" + $script:PSGetRequireLicenseAcceptanceFormatVersion = "2.0" #Bootstrap NuGet binaries Install-NuGetBinaries @@ -27,10 +27,9 @@ function SuiteSetup { RemoveItem $script:PSGalleryRepoPath $null = New-Item -Path $script:PSGalleryRepoPath -ItemType Directory -Force - $script:moduleSourcesFilePath= Join-Path $script:PSGetLocalAppDataPath "PSRepositories.xml" + $script:moduleSourcesFilePath = Join-Path $script:PSGetLocalAppDataPath "PSRepositories.xml" $script:moduleSourcesBackupFilePath = Join-Path $script:PSGetLocalAppDataPath "PSRepositories.xml_$(get-random)_backup" - if(Test-Path $script:moduleSourcesFilePath) - { + if (Test-Path $script:moduleSourcesFilePath) { Rename-Item $script:moduleSourcesFilePath $script:moduleSourcesBackupFilePath -Force } @@ -40,7 +39,7 @@ function SuiteSetup { AssertEquals $modSource.SourceLocation $script:PSGalleryRepoPath "Test repository's SourceLocation is not set properly" AssertEquals $modSource.PublishLocation $script:PSGalleryRepoPath "Test repository's PublishLocation is not set properly" - $script:ApiKey="TestPSGalleryApiKey" + $script:ApiKey = "TestPSGalleryApiKey" # Create temp module to be published $script:TempModulesPath = Join-Path -Path $script:TempPath -ChildPath "PSGet_$(Get-Random)" @@ -52,12 +51,10 @@ function SuiteSetup { } function SuiteCleanup { - if(Test-Path $script:moduleSourcesBackupFilePath) - { + if (Test-Path $script:moduleSourcesBackupFilePath) { Move-Item $script:moduleSourcesBackupFilePath $script:moduleSourcesFilePath -Force } - else - { + else { RemoveItem $script:moduleSourcesFilePath } @@ -68,7 +65,7 @@ function SuiteCleanup { RemoveItem $script:TempModulesPath } -Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.UpdateModuleManifest -Tags 'BVT','InnerLoop' { +Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.UpdateModuleManifest -Tags 'BVT', 'InnerLoop' { BeforeAll { SuiteSetup } @@ -81,25 +78,25 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.UpdateModuleManifest -Ta RemoveItem "$script:PSGalleryRepoPath\*" RemoveItem "$script:PublishModuleBase\*" } - + # Purpose: Validate Update-ModuleManifest sets RequireLicenseAcceptance flag # # Action: # Update-ModuleManifest -RequireLicenseAcceptance # Expected Result: Update-ModuleManifest should update the manifest with RequireLicenseAcceptance value # - It UpdateModuleManifestWithRequireLicenseAcceptance { - New-ModuleManifest -Path "$script:PublishModuleBase\$script:PublishModuleName.psd1" - Update-ModuleManifest -Path "$script:PublishModuleBase\$script:PublishModuleName.psd1" -RequireLicenseAcceptance - $moduleInfo = Test-ModuleManifest -Path "$script:PublishModuleBase\$script:PublishModuleName.psd1" - $moduleInfo.PrivateData.PSData.RequireLicenseAcceptance | should be $true - } + It UpdateModuleManifestWithRequireLicenseAcceptance { + New-ModuleManifest -Path "$script:PublishModuleBase\$script:PublishModuleName.psd1" + Update-ModuleManifest -Path "$script:PublishModuleBase\$script:PublishModuleName.psd1" -RequireLicenseAcceptance + $moduleInfo = Test-ModuleManifest -Path "$script:PublishModuleBase\$script:PublishModuleName.psd1" + $moduleInfo.PrivateData.PSData.RequireLicenseAcceptance | should be $true + } } -Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.Publish -Tags 'BVT','InnerLoop' { - # Not executing these tests on Linux and MacOS as +Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.Publish -Tags 'BVT', 'InnerLoop' { + # Not executing these tests on Linux and MacOS as # the total execution time is exceeding allowed 50 min in TravisCI daily builds. - if($IsMacOS -or $IsLinux) { + if ($IsMacOS -or $IsLinux) { return } @@ -122,7 +119,7 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.Publish -Tags 'BVT','Inn RemoveItem "$script:ProgramFilesModulesPath\$script:PublishModuleName" RemoveItem "$script:PublishModuleBase\*" } - + # Purpose: Publish module that requires license acceptance # # Action: @@ -134,13 +131,13 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.Publish -Tags 'BVT','Inn # It "PublishModuleRequiresLicenseAcceptance" { $version = "1.0" - New-ModuleManifest -Path $ModuleManifestFilePath -ModuleVersion $version -Description "$script:PublishModuleName module" -NestedModules "$script:PublishModuleName.psm1" + New-ModuleManifest -Path $ModuleManifestFilePath -ModuleVersion $version -Description "$script:PublishModuleName module" -NestedModules "$script:PublishModuleName.psm1" Update-ModuleManifest -Path $ModuleManifestFilePath -LicenseUri "http://$script:PublishModuleName.com/license" Update-ModuleManifest -Path $ModuleManifestFilePath -RequireLicenseAcceptance Set-Content $LicenseFilePath -Value "LicenseTerms" - + Publish-Module -Path $script:PublishModuleBase -NuGetApiKey $script:ApiKey - $psgetItemInfo = Find-Module $script:PublishModuleName -RequiredVersion $version + $psgetItemInfo = Find-Module $script:PublishModuleName -RequiredVersion $version $psgetItemInfo.AdditionalMetadata.requireLicenseAcceptance | should be "True" $psgetItemInfo.PowerShellGetFormatVersion | should be $script:PSGetRequireLicenseAcceptanceFormatVersion } @@ -149,40 +146,40 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.Publish -Tags 'BVT','Inn # # Action: # Update-ModuleManifest -RequireLicenseAcceptance - # Update-ModuleManifest -LicenseUri + # Update-ModuleManifest -LicenseUri # Publish-Module # Expected Result: It fails with LicenseTxtNotFound error # It "PublishModuleWithoutLicenseTxt" { $version = "1.0" - New-ModuleManifest -Path $ModuleManifestFilePath -ModuleVersion $version -Description "$script:PublishModuleName module" -NestedModules "$script:PublishModuleName.psm1" + New-ModuleManifest -Path $ModuleManifestFilePath -ModuleVersion $version -Description "$script:PublishModuleName module" -NestedModules "$script:PublishModuleName.psm1" Update-ModuleManifest -Path $ModuleManifestFilePath -LicenseUri "http://$script:PublishModuleName.com/license" - Update-ModuleManifest -Path $ModuleManifestFilePath -RequireLicenseAcceptance - - AssertFullyQualifiedErrorIdEquals -scriptblock {Publish-Module -Path $script:PublishModuleBase -NuGetApiKey $script:ApiKey -WarningAction SilentlyContinue}` - -expectedFullyQualifiedErrorId 'LicenseTxtNotFound,Publish-PSArtifactUtility' + Update-ModuleManifest -Path $ModuleManifestFilePath -RequireLicenseAcceptance + + AssertFullyQualifiedErrorIdEquals -scriptblock { Publish-Module -Path $script:PublishModuleBase -NuGetApiKey $script:ApiKey -WarningAction SilentlyContinue }` + -expectedFullyQualifiedErrorId 'LicenseTxtNotFound,Publish-PSArtifactUtility' } - + # Purpose: Publish module without LicenseURI # # Action: - # Update-ModuleManifest -RequireLicenseAcceptance + # Update-ModuleManifest -RequireLicenseAcceptance # Add License.txt # Publish-Module # Expected Result: It fails with LicenseUriNotSpecified error # It "PublishModuleWithoutLicenseUri" { $version = "1.0" - New-ModuleManifest -Path $ModuleManifestFilePath -ModuleVersion $version -Description "$script:PublishModuleName module" -NestedModules "$script:PublishModuleName.psm1" - Update-ModuleManifest -Path $ModuleManifestFilePath -RequireLicenseAcceptance - Set-Content $LicenseFilePath -Value "LicenseTerms" - AssertFullyQualifiedErrorIdEquals -scriptblock {Publish-Module -Path $script:PublishModuleBase -NuGetApiKey $script:ApiKey -WarningAction SilentlyContinue}` - -expectedFullyQualifiedErrorId 'LicenseUriNotSpecified,Publish-PSArtifactUtility' + New-ModuleManifest -Path $ModuleManifestFilePath -ModuleVersion $version -Description "$script:PublishModuleName module" -NestedModules "$script:PublishModuleName.psm1" + Update-ModuleManifest -Path $ModuleManifestFilePath -RequireLicenseAcceptance + Set-Content $LicenseFilePath -Value "LicenseTerms" + AssertFullyQualifiedErrorIdEquals -scriptblock { Publish-Module -Path $script:PublishModuleBase -NuGetApiKey $script:ApiKey -WarningAction SilentlyContinue }` + -expectedFullyQualifiedErrorId 'LicenseUriNotSpecified,Publish-PSArtifactUtility' } - + # Purpose: Publish module without setting requireLicenseAcceptance # # Action: @@ -193,20 +190,20 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.Publish -Tags 'BVT','Inn # It "PublishModuleNoRequireLicenseAcceptance" { $version = "1.0" - New-ModuleManifest -Path $ModuleManifestFilePath -ModuleVersion $version -Description "$script:PublishModuleName module" -NestedModules "$script:PublishModuleName.psm1" - Update-ModuleManifest -Path $ModuleManifestFilePath -LicenseUri "http://$script:PublishModuleName.com/license" + New-ModuleManifest -Path $ModuleManifestFilePath -ModuleVersion $version -Description "$script:PublishModuleName module" -NestedModules "$script:PublishModuleName.psm1" + Update-ModuleManifest -Path $ModuleManifestFilePath -LicenseUri "http://$script:PublishModuleName.com/license" Set-Content $LicenseFilePath -Value "LicenseTerms" - + Publish-Module -Path $script:PublishModuleBase -NuGetApiKey $script:ApiKey $psgetItemInfo = Find-Module $script:PublishModuleName -RequiredVersion $version - $psgetItemInfo.AdditionalMetadata.requireLicenseAcceptance | should be "False" + $psgetItemInfo.AdditionalMetadata.requireLicenseAcceptance | should be "False" } } function InstallSuiteSetup { Import-Module "$PSScriptRoot\PSGetTestUtils.psm1" -WarningAction SilentlyContinue Import-Module "$PSScriptRoot\Asserts.psm1" -WarningAction SilentlyContinue - + $script:ProgramFilesModulesPath = Get-AllUsersModulesPath $script:MyDocumentsModulesPath = Get-CurrentUserModulesPath $script:PSGetLocalAppDataPath = Get-PSGetLocalAppDataPath @@ -218,27 +215,24 @@ function InstallSuiteSetup { $psgetModuleInfo = Import-Module PowerShellGet -Global -Force -Passthru Import-LocalizedData script:LocalizedData -filename PSGet.Resource.psd1 -BaseDirectory $psgetModuleInfo.ModuleBase - $script:moduleSourcesFilePath= Join-Path $script:PSGetLocalAppDataPath "PSRepositories.xml" + $script:moduleSourcesFilePath = Join-Path $script:PSGetLocalAppDataPath "PSRepositories.xml" $script:moduleSourcesBackupFilePath = Join-Path $script:PSGetLocalAppDataPath "PSRepositories.xml_$(get-random)_backup" - if(Test-Path $script:moduleSourcesFilePath) - { + if (Test-Path $script:moduleSourcesFilePath) { Rename-Item $script:moduleSourcesFilePath $script:moduleSourcesBackupFilePath -Force } - $Global:PSGallerySourceUri = '' + $Global:PSGallerySourceUri = '' GetAndSet-PSGetTestGalleryDetails -SetPSGallery -PSGallerySourceUri ([REF]$Global:PSGallerySourceUri) -IsScriptSuite - PSGetTestUtils\Uninstall-Module ModuleRequireLicenseAcceptance + PSGetTestUtils\Uninstall-Module ModuleRequireLicenseAcceptance Get-InstalledScript -Name ScriptRequireLicenseAcceptance -ErrorAction SilentlyContinue | Uninstall-Script -Force } function InstallSuiteCleanup { - if(Test-Path $script:moduleSourcesBackupFilePath) - { + if (Test-Path $script:moduleSourcesBackupFilePath) { Move-Item $script:moduleSourcesBackupFilePath $script:moduleSourcesFilePath -Force } - else - { + else { RemoveItem $script:moduleSourcesFilePath } @@ -246,7 +240,7 @@ function InstallSuiteCleanup { $null = Import-PackageProvider -Name PowerShellGet -Force } -Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags 'BVT','InnerLoop' { +Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags 'BVT', 'InnerLoop' { BeforeAll { InstallSuiteSetup @@ -259,9 +253,9 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags AfterEach { Get-InstalledScript -Name ScriptRequireLicenseAcceptance -ErrorAction SilentlyContinue | Uninstall-Script -Force -ErrorAction SilentlyContinue PSGetTestUtils\Uninstall-Module ModuleWithDependency - PSGetTestUtils\Uninstall-Module ModuleRequireLicenseAcceptance - } - + PSGetTestUtils\Uninstall-Module ModuleRequireLicenseAcceptance + } + # Purpose: InstallModuleRequiringLicenseAcceptanceAndNoToPrompt # # Action: Install-Module ModuleRequireLicenseAcceptance @@ -270,24 +264,21 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags # It "InstallModuleRequiringLicenseAcceptanceAndNoToPrompt" { $outputPath = $script:TempPath - $guid = [system.guid]::newguid().tostring() + $guid = [system.guid]::newguid().tostring() $outputFilePath = Join-Path $outputPath "$guid" $runspace = CreateRunSpace $outputFilePath 1 # 2 is mapped to NO in ShouldProcess prompt - $Global:proxy.UI.ChoiceToMake=2 + $Global:proxy.UI.ChoiceToMake = 2 $content = $null - try - { + try { $result = ExecuteCommand $runspace 'Install-Module ModuleRequireLicenseAcceptance -Repository PSGallery' } - finally - { + finally { $fileName = "PromptForChoice-0.txt" $path = join-path $outputFilePath $fileName - if(Test-Path $path) - { + if (Test-Path $path) { $content = get-content $path } @@ -303,7 +294,7 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable AssertNull $res "Install-Module should not install a module if Confirm is not accepted" } ` - -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) + -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) # Purpose: InstallModuleRequiringLicenseAcceptanceAndYesToPrompt # @@ -313,24 +304,21 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags # It "InstallModuleRequiringLicenseAcceptanceAndYesToPrompt" { $outputPath = $script:TempPath - $guid = [system.guid]::newguid().tostring() + $guid = [system.guid]::newguid().tostring() $outputFilePath = Join-Path $outputPath "$guid" $runspace = CreateRunSpace $outputFilePath 1 # 0 is mapped to YES in ShouldProcess prompt - $Global:proxy.UI.ChoiceToMake=0 + $Global:proxy.UI.ChoiceToMake = 0 $content = $null - try - { + try { $result = ExecuteCommand $runspace 'Install-Module ModuleRequireLicenseAcceptance' } - finally - { + finally { $fileName = "PromptForChoice-0.txt" $path = join-path $outputFilePath $fileName - if(Test-Path $path) - { + if (Test-Path $path) { $content = get-content $path } @@ -346,7 +334,7 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance")) "Install-Module should install a module if Confirm is accepted" } ` - -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) + -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) # Purpose: InstallModuleAcceptLicense # @@ -355,11 +343,11 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags # Expected Result: module is installed successfully # It "InstallModuleAcceptLicense" { - Install-Module ModuleRequireLicenseAcceptance -Repository PSGallery -AcceptLicense + Install-Module ModuleRequireLicenseAcceptance -Repository PSGallery -AcceptLicense -ErrorAction Stop -Verbose 4> .\verbose.txt $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable - Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance")) "Install-Module should install the module if -AcceptLicense is specified" + Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance")) "Install-Module should install the module if -AcceptLicense is specified ($($res | Out-String; Get-content .\verbose.txt; Get-Module -ListAvailable | Out-String)) " } - + # Purpose: InstallModuleForce # @@ -367,12 +355,12 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags # # Expected Result: module should fail to install with error ForceAcceptLicense # - It "InstallModuleForce" { - AssertFullyQualifiedErrorIdEquals -scriptblock {Install-Module ModuleRequireLicenseAcceptance -Repository PSGallery -Force}` - -expectedFullyQualifiedErrorId 'ForceAcceptLicense,Install-Module' + It "InstallModuleForce" { + AssertFullyQualifiedErrorIdEquals -scriptblock { Install-Module ModuleRequireLicenseAcceptance -Repository PSGallery -Force }` + -expectedFullyQualifiedErrorId 'ForceAcceptLicense,Install-Module' } - + # Purpose: InstallModuleWithDependencyAndYesToPrompt # # Action: Install-Module ModuleWithDependency @@ -381,24 +369,21 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags # It "InstallModuleWithDependencyAndYesToPrompt" { $outputPath = $script:TempPath - $guid = [system.guid]::newguid().tostring() + $guid = [system.guid]::newguid().tostring() $outputFilePath = Join-Path $outputPath "$guid" $runspace = CreateRunSpace $outputFilePath 1 # 0 is mapped to YES in ShouldProcess prompt - $Global:proxy.UI.ChoiceToMake=0 + $Global:proxy.UI.ChoiceToMake = 0 $content = $null - try - { + try { $result = ExecuteCommand $runspace 'Install-Module ModuleWithDependency' } - finally - { + finally { $fileName = "PromptForChoice-0.txt" $path = join-path $outputFilePath $fileName - if(Test-Path $path) - { + if (Test-Path $path) { $content = get-content $path } @@ -408,7 +393,7 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags $itemInfo = Find-Module ModuleRequireLicenseAcceptance -Repository PSGallery $installShouldProcessMessage = $script:LocalizedData.AcceptanceLicenseQuery -f ($itemInfo.Name) - Assert ($content -and ($content -match $installShouldProcessMessage)) "Install Module confirm prompt is not working, Expected:$installShouldProcessMessage, Actual:$content" + Assert ($content -and ($content -match $installShouldProcessMessage)) "Install Module confirm prompt is not working, Expected:$installShouldProcessMessage, Actual:$content" $res = Get-Module ModuleWithDependency -ListAvailable Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleWithDependency")) "Install-Module should install a module if Confirm is accepted" @@ -416,7 +401,7 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance")) "Install-Module should install a module if Confirm is accepted" } ` - -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) + -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) # Purpose: InstallModuleWithDependencyAndNoToPrompt # @@ -426,24 +411,21 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags # It "InstallModuleWithDependencyAndNoToPrompt" { $outputPath = $script:TempPath - $guid = [system.guid]::newguid().tostring() + $guid = [system.guid]::newguid().tostring() $outputFilePath = Join-Path $outputPath "$guid" $runspace = CreateRunSpace $outputFilePath 1 # 2 is mapped to NO in ShouldProcess prompt - $Global:proxy.UI.ChoiceToMake=2 + $Global:proxy.UI.ChoiceToMake = 2 $content = $null - try - { + try { $result = ExecuteCommand $runspace 'Install-Module ModuleWithDependency -Repository PSGallery' } - finally - { + finally { $fileName = "PromptForChoice-0.txt" $path = join-path $outputFilePath $fileName - if(Test-Path $path) - { + if (Test-Path $path) { $content = get-content $path } @@ -462,7 +444,7 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags $res = Get-Module ModuleWithDependency -ListAvailable AssertNull $res "Install-Module should not install a module if Confirm is not accepted" } ` - -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) + -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) # Purpose: InstallModuleWithDependencyAcceptLicense # @@ -471,14 +453,14 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags # Expected Result: module is installed successfully # It "InstallModuleWithDependencyAcceptLicense" { - Install-Module ModuleWithDependency -AcceptLicense + Install-Module ModuleWithDependency -AcceptLicense -ErrorAction Stop $res = Get-Module ModuleWithDependency -ListAvailable Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleWithDependency")) "Install-Module should install the module if -AcceptLicense is specified" - + $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance")) "Install-Module should install the module if -AcceptLicense is specified" - } + } # Purpose: InstallScriptAndYesToPrompt # @@ -488,24 +470,21 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags # It "InstallScriptAndYesToPrompt" { $outputPath = $script:TempPath - $guid = [system.guid]::newguid().tostring() + $guid = [system.guid]::newguid().tostring() $outputFilePath = Join-Path $outputPath "$guid" $runspace = CreateRunSpace $outputFilePath 1 # 0 is mapped to YES in ShouldProcess prompt - $Global:proxy.UI.ChoiceToMake=0 + $Global:proxy.UI.ChoiceToMake = 0 $content = $null - try - { + try { $result = ExecuteCommand $runspace 'Install-Script ScriptRequireLicenseAcceptance -NoPathUpdate' } - finally - { + finally { $fileName = "PromptForChoice-0.txt" $path = join-path $outputFilePath $fileName - if(Test-Path $path) - { + if (Test-Path $path) { $content = get-content $path } @@ -516,16 +495,16 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags $itemInfo = Find-Module ModuleRequireLicenseAcceptance -Repository PSGallery $installShouldProcessMessage = $script:LocalizedData.AcceptanceLicenseQuery -f ($itemInfo.Name) Assert ($content -and ($content -match $installShouldProcessMessage)) "Install script confirm prompt is not working, Expected:$installShouldProcessMessage, Actual:$content" - + $res = Get-InstalledScript ScriptRequireLicenseAcceptance AssertEquals $res.Name "ScriptRequireLicenseAcceptance" "Install-Script failed to install $scriptName, $res" $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance")) "Install-Module should install a module if Confirm is accepted" } ` - -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) + -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) + - # Purpose: InstallScriptAndNoToPrompt # # Action: Install-Script ScriptRequireLicenseAcceptance @@ -534,24 +513,21 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags # It "InstallScriptAndNoToPrompt" { $outputPath = $script:TempPath - $guid = [system.guid]::newguid().tostring() + $guid = [system.guid]::newguid().tostring() $outputFilePath = Join-Path $outputPath "$guid" - $runspace = CreateRunSpace $outputFilePath 1 + $runspace = CreateRunSpace $outputFilePath 1 # 2 is mapped to NO in ShouldProcess prompt - $Global:proxy.UI.ChoiceToMake=2 + $Global:proxy.UI.ChoiceToMake = 2 $content = $null - try - { + try { $result = ExecuteCommand $runspace 'Install-Script ScriptRequireLicenseAcceptance -NoPathUpdate' } - finally - { + finally { $fileName = "PromptForChoice-0.txt" $path = join-path $outputFilePath $fileName - if(Test-Path $path) - { + if (Test-Path $path) { $content = get-content $path } @@ -565,13 +541,13 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags $res = Get-InstalledScript ScriptRequireLicenseAcceptance -ErrorAction SilentlyContinue AssertNull $res "Script should not be installed" - + $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable - AssertNull $res "Dependant module should not be installed if Confirm is not accepted" - } ` - -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) + AssertNull $res "Dependant module should not be installed if Confirm is not accepted" + } ` + -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) + - # Purpose: InstallScriptAcceptLicense # # Action: Install-Script ScriptRequireLicenseAcceptance -AcceptLicennse @@ -579,14 +555,14 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags # Expected Result: script and dependant module are installed successfully # It "InstallScriptAcceptLicense" { - Install-Script ScriptRequireLicenseAcceptance -AcceptLicense -NoPathUpdate + Install-Script ScriptRequireLicenseAcceptance -AcceptLicense -NoPathUpdate -ErrorAction Stop $res = Get-InstalledScript ScriptRequireLicenseAcceptance AssertEquals $res.Name "ScriptRequireLicenseAcceptance" "Install-Script failed to install $scriptName, $res" - + $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance")) "Install-Module should install the module if -AcceptLicense is specified" - } + } # Purpose: SaveModuleRequiringLicenseAcceptanceAndNoToPrompt # @@ -596,24 +572,21 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags # It "SaveModuleRequiringLicenseAcceptanceAndNoToPrompt" { $outputPath = $script:TempPath - $guid = [system.guid]::newguid().tostring() + $guid = [system.guid]::newguid().tostring() $outputFilePath = Join-Path $outputPath "$guid" $runspace = CreateRunSpace $outputFilePath 1 # 2 is mapped to NO in ShouldProcess prompt - $Global:proxy.UI.ChoiceToMake=2 + $Global:proxy.UI.ChoiceToMake = 2 $content = $null - try - { + try { $result = ExecuteCommand $runspace "Save-Module ModuleRequireLicenseAcceptance -Path $script:MyDocumentsModulesPath -ErrorAction SilentlyContinue" } - finally - { + finally { $fileName = "PromptForChoice-0.txt" $path = join-path $outputFilePath $fileName - if(Test-Path $path) - { + if (Test-Path $path) { $content = get-content $path } @@ -629,7 +602,7 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable AssertNull $res "Save-Module should not install a module if Confirm is not accepted" } ` - -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) + -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) # Purpose: SaveModuleRequiringLicenseAcceptanceAndYesToPrompt # @@ -639,24 +612,21 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags # It "SaveModuleRequiringLicenseAcceptanceAndYesToPrompt" { $outputPath = $script:TempPath - $guid = [system.guid]::newguid().tostring() + $guid = [system.guid]::newguid().tostring() $outputFilePath = Join-Path $outputPath "$guid" $runspace = CreateRunSpace $outputFilePath 1 # 0 is mapped to YES in ShouldProcess prompt - $Global:proxy.UI.ChoiceToMake=0 + $Global:proxy.UI.ChoiceToMake = 0 $content = $null - try - { + try { $result = ExecuteCommand $runspace "Save-Module ModuleRequireLicenseAcceptance -Path $script:MyDocumentsModulesPath" } - finally - { + finally { $fileName = "PromptForChoice-0.txt" $path = join-path $outputFilePath $fileName - if(Test-Path $path) - { + if (Test-Path $path) { $content = get-content $path } @@ -672,7 +642,7 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance")) "save-Module should save a module if Confirm is accepted" } ` - -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) + -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) # Purpose: SaveModuleAcceptLicense # @@ -681,7 +651,7 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags # Expected Result: module is saved successfully # It "SaveModuleAcceptLicense" { - Save-Module ModuleRequireLicenseAcceptance -Repository PSGallery -AcceptLicense -Path $script:MyDocumentsModulesPath + Save-Module ModuleRequireLicenseAcceptance -Repository PSGallery -AcceptLicense -Path $script:MyDocumentsModulesPath -ErrorAction Stop $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance")) "Install-Module should install the module if -AcceptLicense is specified" } @@ -692,9 +662,9 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags # # Expected Result: module should fail to save with error ForceAcceptLicense # - It "SaveModuleForce" { - AssertFullyQualifiedErrorIdEquals -scriptblock {Save-Module ModuleRequireLicenseAcceptance -Repository PSGallery -Force -Path $script:MyDocumentsModulesPath -WarningAction SilentlyContinue}` - -expectedFullyQualifiedErrorId 'ForceAcceptLicense,Install-Module' + It "SaveModuleForce" { + AssertFullyQualifiedErrorIdEquals -scriptblock { Save-Module ModuleRequireLicenseAcceptance -Repository PSGallery -Force -Path $script:MyDocumentsModulesPath -WarningAction SilentlyContinue }` + -expectedFullyQualifiedErrorId 'ForceAcceptLicense,Install-Module' } # Purpose: SaveModuleWithDependencyAndYesToPrompt @@ -705,24 +675,21 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags # It "SaveModuleWithDependencyAndYesToPrompt" { $outputPath = $script:TempPath - $guid = [system.guid]::newguid().tostring() + $guid = [system.guid]::newguid().tostring() $outputFilePath = Join-Path $outputPath "$guid" $runspace = CreateRunSpace $outputFilePath 1 # 0 is mapped to YES in ShouldProcess prompt - $Global:proxy.UI.ChoiceToMake=0 + $Global:proxy.UI.ChoiceToMake = 0 $content = $null - try - { + try { $result = ExecuteCommand $runspace "Save-Module ModuleWithDependency -Path $script:MyDocumentsModulesPath" } - finally - { + finally { $fileName = "PromptForChoice-0.txt" $path = join-path $outputFilePath $fileName - if(Test-Path $path) - { + if (Test-Path $path) { $content = get-content $path } @@ -732,7 +699,7 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags $itemInfo = Find-Module ModuleRequireLicenseAcceptance -Repository PSGallery $SaveShouldProcessMessage = $script:LocalizedData.AcceptanceLicenseQuery -f ($itemInfo.Name) - Assert ($content -and ($content -match $SaveShouldProcessMessage)) "Save Module confirm prompt is not working, Expected:$installShouldProcessMessage, Actual:$content" + Assert ($content -and ($content -match $SaveShouldProcessMessage)) "Save Module confirm prompt is not working, Expected:$installShouldProcessMessage, Actual:$content" $res = Get-Module ModuleWithDependency -ListAvailable Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleWithDependency")) "Save-Module should Save a module if Confirm is accepted" @@ -740,7 +707,7 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance")) "Save-Module should Save a module if Confirm is accepted" } ` - -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) + -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) # Purpose: SaveModuleWithDependencyAndNoToPrompt # @@ -750,24 +717,21 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags # It "SaveModuleWithDependencyAndNoToPrompt" { $outputPath = $script:TempPath - $guid = [system.guid]::newguid().tostring() + $guid = [system.guid]::newguid().tostring() $outputFilePath = Join-Path $outputPath "$guid" $runspace = CreateRunSpace $outputFilePath 1 # 2 is mapped to NO in ShouldProcess prompt - $Global:proxy.UI.ChoiceToMake=2 + $Global:proxy.UI.ChoiceToMake = 2 $content = $null - try - { + try { $result = ExecuteCommand $runspace "Save-Module ModuleWithDependency -Path $script:MyDocumentsModulesPath -ErrorAction SilentlyContinue" } - finally - { + finally { $fileName = "PromptForChoice-0.txt" $path = join-path $outputFilePath $fileName - if(Test-Path $path) - { + if (Test-Path $path) { $content = get-content $path } @@ -775,7 +739,7 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags RemoveItem $outputFilePath } - $itemInfo = Find-Module ModuleRequireLicenseAcceptance -Repository PSGallery + $itemInfo = Find-Module ModuleRequireLicenseAcceptance -Repository PSGallery $saveShouldProcessMessage = $script:LocalizedData.AcceptanceLicenseQuery -f ($itemInfo.Name) Assert ($content -and ($content -match $saveShouldProcessMessage)) "Save module confirm prompt is not working, Expected:$installShouldProcessMessage, Actual:$content" @@ -786,7 +750,7 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags $res = Get-Module ModuleWithDependency -ListAvailable AssertNull $res "Save-Module should not install a module if Confirm is not accepted" } ` - -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) + -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) # Purpose: SaveModuleWithDependencyAcceptLicense @@ -796,15 +760,15 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags # Expected Result: module is installed successfully # It "SaveModuleWithDependencyAcceptLicense" { - Save-Module ModuleWithDependency -AcceptLicense -Path $script:MyDocumentsModulesPath + Save-Module ModuleWithDependency -AcceptLicense -Path $script:MyDocumentsModulesPath -ErrorAction Stop $res = Get-Module ModuleWithDependency -ListAvailable Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleWithDependency")) "Install-Module should install the module if -AcceptLicense is specified" - + $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance")) "Install-Module should install the module if -AcceptLicense is specified" } - + # Purpose: SaveScriptAndYesToPrompt # # Action: Save-Script ScriptRequireLicenseAcceptance @@ -813,24 +777,21 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags # It "SaveScriptAndYesToPrompt" { $outputPath = $script:TempPath - $guid = [system.guid]::newguid().tostring() + $guid = [system.guid]::newguid().tostring() $outputFilePath = Join-Path $outputPath "$guid" $runspace = CreateRunSpace $outputFilePath 1 # 0 is mapped to YES in ShouldProcess prompt - $Global:proxy.UI.ChoiceToMake=0 + $Global:proxy.UI.ChoiceToMake = 0 $content = $null - try - { + try { $result = ExecuteCommand $runspace "Save-Script ScriptRequireLicenseAcceptance -Path $script:MyDocumentsModulesPath" } - finally - { + finally { $fileName = "PromptForChoice-0.txt" $path = join-path $outputFilePath $fileName - if(Test-Path $path) - { + if (Test-Path $path) { $content = get-content $path } @@ -841,18 +802,17 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags $itemInfo = Find-Module ModuleRequireLicenseAcceptance -Repository PSGallery $SaveShouldProcessMessage = $script:LocalizedData.AcceptanceLicenseQuery -f ($itemInfo.Name) Assert ($content -and ($content -match $SaveShouldProcessMessage)) "Save script confirm prompt is not working, Expected:$installShouldProcessMessage, Actual:$content" - - - - if(-not (Test-Path -Path "$script:MyDocumentsModulesPath\ScriptRequireLicenseAcceptance.ps1" -PathType Leaf)) - { + + + + if (-not (Test-Path -Path "$script:MyDocumentsModulesPath\ScriptRequireLicenseAcceptance.ps1" -PathType Leaf)) { Assert $false "Save-Script should save script $ScriptName" - } + } $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance")) "Save-Module should save a module if Confirm is accepted" } ` - -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) + -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) # Purpose: SaveScriptAcceptLicense # @@ -861,17 +821,16 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags # Expected Result: script and dependant module are Saved successfully # It "SaveScriptAcceptLicense" { - Save-Script ScriptRequireLicenseAcceptance -AcceptLicense -Path $script:MyDocumentsModulesPath + Save-Script ScriptRequireLicenseAcceptance -AcceptLicense -Path $script:MyDocumentsModulesPath -ErrorAction Stop - if(-not (Test-Path -Path "$script:MyDocumentsModulesPath\ScriptRequireLicenseAcceptance.ps1" -PathType Leaf)) - { + if (-not (Test-Path -Path "$script:MyDocumentsModulesPath\ScriptRequireLicenseAcceptance.ps1" -PathType Leaf)) { Assert $false "Save-Script should save script $ScriptName" } - + $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance")) "Save-Module should Save the module if -AcceptLicense is specified" } - + # Purpose: UpdateModuleRequiringLicenseAcceptanceAndNoToPrompt # @@ -880,28 +839,25 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags # Expected Result: Module should not be updated after confirming NO # It "UpdateModuleRequiringLicenseAcceptanceAndNoToPrompt" { - + Install-module ModuleRequireLicenseAcceptance -RequiredVersion 1.0 -AcceptLicense -Force - + $outputPath = $script:TempPath - $guid = [system.guid]::newguid().tostring() + $guid = [system.guid]::newguid().tostring() $outputFilePath = Join-Path $outputPath "$guid" $runspace = CreateRunSpace $outputFilePath 1 # 2 is mapped to NO in ShouldProcess prompt - $Global:proxy.UI.ChoiceToMake=2 + $Global:proxy.UI.ChoiceToMake = 2 $content = $null - try - { + try { $result = ExecuteCommand $runspace 'Update-Module ModuleRequireLicenseAcceptance' } - finally - { + finally { $fileName = "PromptForChoice-0.txt" $path = join-path $outputFilePath $fileName - if(Test-Path $path) - { + if (Test-Path $path) { $content = get-content $path } @@ -916,10 +872,10 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags - $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable + $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance") -and ($res.Version -eq [Version]"1.0")) "Update-Module should not update the module if confirm is declined" } ` - -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) + -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) # Purpose: UpdateModuleRequiringLicenseAcceptanceAndYesToPrompt @@ -933,24 +889,21 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags Install-module ModuleRequireLicenseAcceptance -RequiredVersion 1.0 -AcceptLicense -Force $outputPath = $script:TempPath - $guid = [system.guid]::newguid().tostring() + $guid = [system.guid]::newguid().tostring() $outputFilePath = Join-Path $outputPath "$guid" $runspace = CreateRunSpace $outputFilePath 1 # 0 is mapped to YES in ShouldProcess prompt - $Global:proxy.UI.ChoiceToMake=0 + $Global:proxy.UI.ChoiceToMake = 0 $content = $null - try - { + try { $result = ExecuteCommand $runspace 'Update-Module ModuleRequireLicenseAcceptance' } - finally - { + finally { $fileName = "PromptForChoice-0.txt" $path = join-path $outputFilePath $fileName - if(Test-Path $path) - { + if (Test-Path $path) { $content = get-content $path } @@ -966,7 +919,7 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags $res = Get-InstalledModule ModuleRequireLicenseAcceptance -RequiredVersion 3.0 AssertNotNull $res "Update-Module should Update a module if Confirm is accepted" } ` - -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) + -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) # Purpose: UpdateModuleAcceptLicnese @@ -988,9 +941,9 @@ Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags # # Expected Result: module should fail to Update with error ForceAcceptLicense # - It "UpdateModuleForce" { + It "UpdateModuleForce" { Install-module ModuleRequireLicenseAcceptance -RequiredVersion 1.0 -AcceptLicense -Force - AssertFullyQualifiedErrorIdEquals -scriptblock {Update-Module ModuleRequireLicenseAcceptance -Force}` - -expectedFullyQualifiedErrorId 'ForceAcceptLicense,Update-Module' - } - } + AssertFullyQualifiedErrorIdEquals -scriptblock { Update-Module ModuleRequireLicenseAcceptance -Force }` + -expectedFullyQualifiedErrorId 'ForceAcceptLicense,Update-Module' + } +} diff --git a/imgs/readme-getmodule-1.png b/imgs/readme-getmodule-1.png new file mode 100644 index 00000000..bc2718b8 Binary files /dev/null and b/imgs/readme-getmodule-1.png differ diff --git a/src/PowerShellGet/PSGet.Resource.psd1 b/src/PowerShellGet/PSGet.Resource.psd1 index b6704d17..8d472b70 100644 --- a/src/PowerShellGet/PSGet.Resource.psd1 +++ b/src/PowerShellGet/PSGet.Resource.psd1 @@ -22,6 +22,7 @@ ConvertFrom-StringData @' RequiredVersionAllowedOnlyWithSingleModuleName=The RequiredVersion parameter is allowed only when a single module name is specified as the value of the Name parameter, without any wildcard characters. MinimumVersionIsGreaterThanMaximumVersion=The specified MinimumVersion '{0}' is greater than the specified MaximumVersion '{1}'. AllowPrereleaseRequiredToUsePrereleaseStringInVersion=The '-AllowPrerelease' parameter must be specified when using the Prerelease string in MinimumVersion, MaximumVersion, or RequiredVersion. + UpdateModuleAdminPrivilegeRequiredForAllUsersScope=Administrator rights are required to update modules in '{0}'. Log on to the computer with an account that has Administrator rights, and then try again, or update '{1}' by adding "-Scope CurrentUser" to your command. You can also try running the Windows PowerShell session with elevated rights (Run as Administrator). InstallModuleAdminPrivilegeRequiredForAllUsersScope=Administrator rights are required to install modules in '{0}'. Log on to the computer with an account that has Administrator rights, and then try again, or install '{1}' by adding "-Scope CurrentUser" to your command. You can also try running the Windows PowerShell session with elevated rights (Run as Administrator). InstallScriptAdminPrivilegeRequiredForAllUsersScope=Administrator rights are required to install scripts in '{0}'. Log on to the computer with an account that has Administrator rights, and then try again, or install '{1}' by adding "-Scope CurrentUser" to your command. You can also try running the Windows PowerShell session with elevated rights (Run as Administrator). AdministratorRightsNeededOrSpecifyCurrentUserScope=Administrator rights are required to install or update. Log on to the computer with an account that has Administrator rights, and then try again, or install by adding "-Scope CurrentUser" to your command. You can also try running the Windows PowerShell session with elevated rights (Run as Administrator). diff --git a/src/PowerShellGet/PowerShellGet.psd1 b/src/PowerShellGet/PowerShellGet.psd1 index 4d50574d..43ba70ac 100644 --- a/src/PowerShellGet/PowerShellGet.psd1 +++ b/src/PowerShellGet/PowerShellGet.psd1 @@ -1,59 +1,51 @@ @{ - RootModule = 'PSModule.psm1' - ModuleVersion = '2.1.2' - GUID = '1d73a601-4a6c-43c5-ba3f-619b18bbb404' - Author = 'Microsoft Corporation' - CompanyName = 'Microsoft Corporation' - Copyright = '(c) Microsoft Corporation. All rights reserved.' - Description = 'PowerShell module with commands for discovering, installing, updating and publishing the PowerShell artifacts like Modules, DSC Resources, Role Capabilities and Scripts.' - PowerShellVersion = '3.0' - FormatsToProcess = 'PSGet.Format.ps1xml' - FunctionsToExport = @( - 'Find-Command', - 'Find-DSCResource', - 'Find-Module', - 'Find-RoleCapability', - 'Find-Script', - 'Get-InstalledModule', - 'Get-InstalledScript', - 'Get-PSRepository', - 'Install-Module', - 'Install-Script', - 'New-ScriptFileInfo', - 'Publish-Module', - 'Publish-Script', - 'Register-PSRepository', - 'Save-Module', - 'Save-Script', - 'Set-PSRepository', - 'Test-ScriptFileInfo', - 'Uninstall-Module', - 'Uninstall-Script', - 'Unregister-PSRepository', - 'Update-Module', - 'Update-ModuleManifest', - 'Update-Script', - 'Update-ScriptFileInfo') - - VariablesToExport = "*" - AliasesToExport = @('inmo', 'fimo', 'upmo', 'pumo') - FileList = @('PSModule.psm1', - 'PSGet.Format.ps1xml', - 'PSGet.Resource.psd1') - RequiredModules = @(@{ModuleName = 'PackageManagement'; ModuleVersion = '1.1.7.0'}) - PrivateData = @{ - "PackageManagementProviders" = 'PSModule.psm1' - "SupportedPowerShellGetFormatVersions" = @('1.x', '2.x') - PSData = @{ - Tags = @('Packagemanagement', - 'Provider', - 'PSEdition_Desktop', - 'PSEdition_Core', - 'Linux', - 'Mac') - ProjectUri = 'https://go.microsoft.com/fwlink/?LinkId=828955' - LicenseUri = 'https://go.microsoft.com/fwlink/?LinkId=829061' - ReleaseNotes = @' + RootModule = 'PSModule.psm1' + ModuleVersion = '2.1.4' + Description = 'PowerShell module with commands for discovering, installing, updating and publishing the PowerShell artifacts like Modules, DSC Resources, Role Capabilities and Scripts.' + PowerShellVersion = '3.0' + FormatsToProcess = 'PSGet.Format.ps1xml' + FunctionsToExport = @( + 'Find-Command', + 'Find-DSCResource', + 'Find-Module', + 'Find-RoleCapability', + 'Find-Script', + 'Get-InstalledModule', + 'Get-InstalledScript', + 'Get-PSRepository', + 'Install-Module', + 'Install-Script', + 'New-ScriptFileInfo', + 'Publish-Module', + 'Publish-Script', + 'Register-PSRepository', + 'Save-Module', + 'Save-Script', + 'Set-PSRepository', + 'Test-ScriptFileInfo', + 'Uninstall-Module', + 'Uninstall-Script', + 'Unregister-PSRepository', + 'Update-Module', + 'Update-ModuleManifest', + 'Update-Script', + 'Update-ScriptFileInfo') + + VariablesToExport = "*" + AliasesToExport = @('inmo', 'fimo', 'upmo', 'pumo') + FileList = @('PSModule.psm1', + 'PSGet.Format.ps1xml', + 'PSGet.Resource.psd1') + RequiredModules = @(@{ModuleName = 'PackageManagement'; ModuleVersion = '1.1.7.0' }) + PrivateData = @{ + "PackageManagementProviders" = 'PSModule.psm1' + "SupportedPowerShellGetFormatVersions" = @('1.x', '2.x') + RequiredModules = @(@{ModuleName = 'PackageManagement'; ModuleVersion = '1.4' }) + 'Linux', + 'Mac') + ProjectUri = 'https://go.microsoft.com/fwlink/?LinkId=828955' + LicenseUri = 'https://go.microsoft.com/fwlink/?LinkId=829061' + ReleaseNotes = @' ## 2.1.2 New Feature @@ -62,30 +54,27 @@ New Feature ## 2.1.1 -- Fix DSC resource folder structure -## 2.1.0 +## 2.1.4 +- Fixed hang while publishing some packages (#478) -Breaking Change +## 2.1.3 +New Features -- Default installation scope for Update-Module and Update-Script has changed to match Install-Module and Install-Script. For Windows PowerShell (version 5.1 or below), the default scope is AllUsers when running in an elevated session, and CurrentUser at all other times. - For PowerShell version 6.0.0 and above, the default installation scope is always CurrentUser. (#421) +- Added -Scope parameter to Update-Module (Thanks @lwajswaj!) (#471) +- Added -Exclude parameter to Publish-Module (Thanks @Benny1007!) (#191) +- Added -SkipAutomaticTags parameter to Publish-Module (Thanks @awickham10!) (#452) -Bug Fixes +Bug Fix -- Update-ModuleManifest no longer clears FunctionsToExport, AliasesToExport, nor NestModules (#415 & #425) (Thanks @pougetat and @tnieto88!) -- Update-Module no longer changes repository URL (#407) -- Update-ModuleManifest no longer preprends 'PSGet_' to module name (#403) (Thanks @ThePoShWolf) -- Update-ModuleManifest now throws error and fails to update when provided invalid entries (#398) (Thanks @pougetat!) -- Ignore files no longer being included when uploading modules (#396) +- Fixed issue with finding modules using macOS and .NET Core 3.0 -New Features +## 2.1.2 -- New DSC resource, PSRepository (#426) (Thanks @johlju!) -- Piping of PS respositories (#420) -- utf8 support for .nuspec (#419) +New Feature + +- Added support for registering repositories with special characters -## 2.0.4 Bug Fix * Remove PSGallery availability checks (#374) @@ -235,6 +224,32 @@ Bug fixes * Fixed '[Test-ScriptFileInfo] Fails on *NIX newlines (LF vs. CRLF)' (#18) +## 1.1.1.0 + +Bug fixes +* Fixed 'Update-Module fails with `ModuleAuthenticodeSignature` error for modules with signed PSD1'. (#12) (#8) +* Fixed 'Properties of `AdditionalMetadata` are case-sensitive'. #7 +* Changed `ErrorAction` to `Ignore` for few cmdlet usages as they should not show up in ErrorVariable. + - For example, error returned by `Get-Command Test-FileCatalog` should be ignored. + + +## 1.1.0.0 + +* Initial release from GitHub. +* PowerShellCore support. +* Security enhancements including the enforcement of catalog-signed modules during installation. +* Authenticated Repository support. +* Proxy Authentication support. +* Responses to a number of user requests and issues. +'@ +} +} + +HelpInfoURI = 'http://go.microsoft.com/fwlink/?linkid=855963' +} +* Fixed '[Test-ScriptFileInfo] Fails on *NIX newlines (LF vs. CRLF)' (#18) + + ## 1.1.1.0 Bug fixes diff --git a/src/PowerShellGet/private/functions/New-NugetPackage.ps1 b/src/PowerShellGet/private/functions/New-NugetPackage.ps1 index 16cd6502..c4d773ab 100644 --- a/src/PowerShellGet/private/functions/New-NugetPackage.ps1 +++ b/src/PowerShellGet/private/functions/New-NugetPackage.ps1 @@ -19,6 +19,8 @@ function New-NugetPackage { ) Set-StrictMode -Off + Write-Verbose "Calling New-NugetPackage" + if (-Not(Test-Path -Path $NuspecPath -PathType Leaf)) { throw "A nuspec file does not exist at $NuspecPath, provide valid path to a .nuspec" } @@ -27,89 +29,96 @@ function New-NugetPackage { throw "NugetPackageRoot $NugetPackageRoot does not exist" } + $processStartInfo = New-Object System.Diagnostics.ProcessStartInfo if ($PSCmdlet.ParameterSetName -eq "UseNuget") { if (-Not(Test-Path -Path $NuGetExePath)) { throw "Nuget.exe does not exist at $NugetExePath, provide a valid path to nuget.exe" } + $ProcessName = $NugetExePath $ArgumentList = @("pack") $ArgumentList += "`"$NuspecPath`"" - $ArgumentList += "-outputdirectory `"$OutputPath`"" - - $processStartInfo = New-Object System.Diagnostics.ProcessStartInfo - $processStartInfo.FileName = $NugetExePath - $processStartInfo.RedirectStandardError = $true - $processStartInfo.RedirectStandardOutput = $true - $processStartInfo.UseShellExecute = $false - $processStartInfo.Arguments = $ArgumentList - - $process = New-Object System.Diagnostics.Process - $process.StartInfo = $processStartInfo - $process.Start() | Out-Null - $process.WaitForExit() - - if (-Not ($process.ExitCode -eq 0 )) { - $stdErr = $process.StandardError.ReadToEnd() - throw "nuget.exe failed to pack $stdErr" - } + $ArgumentList += "-outputdirectory `"$OutputPath`" -noninteractive" + + $tempPath = $null } + else { + # use Dotnet CLI - if ($PSCmdlet.ParameterSetName -eq "UseDotnetCli") { #perform dotnet pack using a temporary project file. - $dotnetCliPath = (Get-Command -Name "dotnet").Source + $ProcessName = (Get-Command -Name "dotnet").Source $tempPath = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath ([System.Guid]::NewGuid()).Guid New-Item -ItemType Directory -Path $tempPath -Force | Out-Null $CsprojContent = @" - - - NotUsed - Temp project used for creating nupkg file. - netcoreapp2.0 - true - - + + + NotUsed + Temp project used for creating nupkg file. + netcoreapp2.0 + true + + "@ $projectFile = New-Item -ItemType File -Path $tempPath -Name "Temp.csproj" Set-Content -Value $CsprojContent -Path $projectFile - #execution - $ArgumentList = @("pack") $ArgumentList += "`"$projectFile`"" $ArgumentList += "/p:NuspecFile=`"$NuspecPath`"" $ArgumentList += "--output `"$OutputPath`"" + } - $processStartInfo = New-Object System.Diagnostics.ProcessStartInfo - $processStartInfo.FileName = $dotnetCliPath - $processStartInfo.RedirectStandardError = $true - $processStartInfo.RedirectStandardOutput = $true - $processStartInfo.UseShellExecute = $false - $processStartInfo.Arguments = $ArgumentList + # run the packing program + $processStartInfo = New-Object System.Diagnostics.ProcessStartInfo + $processStartInfo.FileName = $ProcessName + $processStartInfo.Arguments = $ArgumentList + $processStartInfo.RedirectStandardError = $true + $processStartInfo.RedirectStandardOutput = $true + $processStartInfo.UseShellExecute = $false + + Write-Verbose "Calling $ProcessName $($ArgumentList -join ' ')" + $process = New-Object System.Diagnostics.Process + $process.StartInfo = $processStartInfo + + $process.Start() | Out-Null + + # read output incrementally, it'll block if it writes too much + $outputLines = @() + Write-Verbose "$ProcessName output:" + while (! $process.HasExited) { + $output = $process.StandardOutput.ReadLine() + Write-Verbose "`t$output" + $outputLines += $output + } - $process = New-Object System.Diagnostics.Process - $process.StartInfo = $processStartInfo - $process.Start() | Out-Null - $process.WaitForExit() + # get any remaining output + $process.WaitForExit() + $outputLines += $process.StandardOutput.ReadToEnd() - if (Test-Path -Path $tempPath) { - Remove-Item -Path $tempPath -Force -Recurse - } + $stdOut = $outputLines -join "`n" - if (-Not ($process.ExitCode -eq 0 )) { - $stdOut = $process.StandardOutput.ReadToEnd() - throw "dotnet cli failed to pack $stdOut" - } + Write-Verbose "finished running $($processStartInfo.FileName) with exit code $($process.ExitCode)" + + if (($tempPath -ne $null) -and (Test-Path -Path $tempPath)) { + Remove-Item -Path $tempPath -Force -Recurse + } + if (-Not ($process.ExitCode -eq 0 )) { + # nuget writes errors to stdErr, dotnet writes them to stdOut + if ($UseDotnetCli) { + $errors = $stdOut + } + else { + $errors = $process.StandardError.ReadToEnd() + } + throw "$ProcessName failed to pack: error $errors" } - $stdOut = $process.StandardOutput.ReadToEnd() $stdOut -match "Successfully created package '(.*.nupkg)'" | Out-Null $nupkgFullFile = $matches[1] - $stdOut = $process.StandardOutput.ReadToEnd() - - Write-Verbose -Message $stdOut + Write-Verbose "Created Nuget Package $nupkgFullFile" Write-Output $nupkgFullFile } diff --git a/src/PowerShellGet/private/functions/New-NuspecFile.ps1 b/src/PowerShellGet/private/functions/New-NuspecFile.ps1 index 2e7fa6ef..62f26a30 100644 --- a/src/PowerShellGet/private/functions/New-NuspecFile.ps1 +++ b/src/PowerShellGet/private/functions/New-NuspecFile.ps1 @@ -8,7 +8,7 @@ function New-NuspecFile { [string]$Id, [Parameter(Mandatory = $true)] - [version]$Version, + [string]$Version, [Parameter(Mandatory = $true)] [string]$Description, @@ -49,6 +49,8 @@ function New-NuspecFile { ) Set-StrictMode -Off + Write-Verbose "Calling New-NuspecFile" + $nameSpaceUri = "http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd" [xml]$xml = New-Object System.Xml.XmlDocument @@ -59,10 +61,9 @@ function New-NuspecFile { $packageElement = $xml.CreateElement("package", $nameSpaceUri) $metaDataElement = $xml.CreateElement("metadata", $nameSpaceUri) - #truncate tags if they exceed nuspec specifications for size. - $Tags = $Tags -Join " " - - if ($Tags.Length -gt 4000) { + # warn we're over 4000 characters for standard nuget servers + $tagsString = $Tags -Join " " + if ($tagsString.Length -gt 4000) { Write-Warning -Message "Tag list exceeded 4000 characters and may not be accepted by some Nuget feeds." } @@ -75,7 +76,7 @@ function New-NuspecFile { releaseNotes = $ReleaseNotes requireLicenseAcceptance = $RequireLicenseAcceptance.ToString().ToLower() copyright = $Copyright - tags = $Tags + tags = $tagsString } if ($LicenseUrl) { $metaDataElementsHash.Add("licenseUrl", $LicenseUrl) } diff --git a/src/PowerShellGet/private/functions/Publish-NugetPackage.ps1 b/src/PowerShellGet/private/functions/Publish-NugetPackage.ps1 index d410bd30..d470dba4 100644 --- a/src/PowerShellGet/private/functions/Publish-NugetPackage.ps1 +++ b/src/PowerShellGet/private/functions/Publish-NugetPackage.ps1 @@ -18,6 +18,7 @@ function Publish-NugetPackage { ) Set-StrictMode -Off + Write-Verbose "Calling Publish-NugetPackage -NupkgPath $NupkgPath -Destination $Destination -NugetExePath $NugetExePath -UseDotnetCli:$UseDotnetCli" $Destination = $Destination.TrimEnd("\") if ($PSCmdlet.ParameterSetName -eq "UseNuget") { diff --git a/src/PowerShellGet/private/functions/Publish-PSArtifactUtility.ps1 b/src/PowerShellGet/private/functions/Publish-PSArtifactUtility.ps1 index 4d93943f..3c3bffe2 100644 --- a/src/PowerShellGet/private/functions/Publish-PSArtifactUtility.ps1 +++ b/src/PowerShellGet/private/functions/Publish-PSArtifactUtility.ps1 @@ -1,67 +1,67 @@ -function Publish-PSArtifactUtility { - [CmdletBinding(PositionalBinding = $false)] +function Publish-PSArtifactUtility +{ + [CmdletBinding(PositionalBinding=$false)] Param ( - [Parameter(Mandatory = $true, ParameterSetName = 'PublishModule')] + [Parameter(Mandatory=$true, ParameterSetName='PublishModule')] [ValidateNotNullOrEmpty()] [PSModuleInfo] $PSModuleInfo, - [Parameter(Mandatory = $true, ParameterSetName = 'PublishScript')] + [Parameter(Mandatory=$true, ParameterSetName='PublishScript')] [ValidateNotNullOrEmpty()] [PSCustomObject] $PSScriptInfo, - [Parameter(Mandatory = $true, ParameterSetName = 'PublishModule')] + [Parameter(Mandatory=$true, ParameterSetName='PublishModule')] [ValidateNotNullOrEmpty()] [string] $ManifestPath, - [Parameter(Mandatory = $true)] + [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $Destination, - [Parameter(Mandatory = $true)] + [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $Repository, - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] + [Parameter(Mandatory=$false)] [string] $NugetApiKey, - [Parameter(Mandatory = $false)] + [Parameter(Mandatory=$false)] [pscredential] $Credential, - [Parameter(Mandatory = $true)] + [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $NugetPackageRoot, - [Parameter(ParameterSetName = 'PublishModule')] + [Parameter(ParameterSetName='PublishModule')] [Version] $FormatVersion, - [Parameter(ParameterSetName = 'PublishModule')] + [Parameter(ParameterSetName='PublishModule')] [string] $ReleaseNotes, - [Parameter(ParameterSetName = 'PublishModule')] + [Parameter(ParameterSetName='PublishModule')] [string[]] $Tags, - [Parameter(ParameterSetName = 'PublishModule')] + [Parameter(ParameterSetName='PublishModule')] [Uri] $LicenseUri, - [Parameter(ParameterSetName = 'PublishModule')] + [Parameter(ParameterSetName='PublishModule')] [Uri] $IconUri, - [Parameter(ParameterSetName = 'PublishModule')] + [Parameter(ParameterSetName='PublishModule')] [Uri] $ProjectUri ) @@ -77,7 +77,8 @@ function Publish-PSArtifactUtility { $Copyright = $null $requireLicenseAcceptance = "false" - if ($PSModuleInfo) { + if($PSModuleInfo) + { $Name = $PSModuleInfo.Name $Description = $PSModuleInfo.Description $Version = $PSModuleInfo.Version @@ -85,54 +86,67 @@ function Publish-PSArtifactUtility { $CompanyName = $PSModuleInfo.CompanyName $Copyright = $PSModuleInfo.Copyright - if ($PSModuleInfo.PrivateData -and - ($PSModuleInfo.PrivateData.GetType().ToString() -eq "System.Collections.Hashtable") -and - $PSModuleInfo.PrivateData["PSData"] -and - ($PSModuleInfo.PrivateData["PSData"].GetType().ToString() -eq "System.Collections.Hashtable") - ) { - if ( -not $Tags -and $PSModuleInfo.PrivateData.PSData["Tags"]) { + if($PSModuleInfo.PrivateData -and + ($PSModuleInfo.PrivateData.GetType().ToString() -eq "System.Collections.Hashtable") -and + $PSModuleInfo.PrivateData["PSData"] -and + ($PSModuleInfo.PrivateData["PSData"].GetType().ToString() -eq "System.Collections.Hashtable") + ) + { + if( -not $Tags -and $PSModuleInfo.PrivateData.PSData["Tags"]) + { $Tags = $PSModuleInfo.PrivateData.PSData.Tags } - if ( -not $ReleaseNotes -and $PSModuleInfo.PrivateData.PSData["ReleaseNotes"]) { + if( -not $ReleaseNotes -and $PSModuleInfo.PrivateData.PSData["ReleaseNotes"]) + { $ReleaseNotes = $PSModuleInfo.PrivateData.PSData.ReleaseNotes } - if ( -not $LicenseUri -and $PSModuleInfo.PrivateData.PSData["LicenseUri"]) { + if( -not $LicenseUri -and $PSModuleInfo.PrivateData.PSData["LicenseUri"]) + { $LicenseUri = $PSModuleInfo.PrivateData.PSData.LicenseUri } - if ( -not $IconUri -and $PSModuleInfo.PrivateData.PSData["IconUri"]) { + if( -not $IconUri -and $PSModuleInfo.PrivateData.PSData["IconUri"]) + { $IconUri = $PSModuleInfo.PrivateData.PSData.IconUri } - if ( -not $ProjectUri -and $PSModuleInfo.PrivateData.PSData["ProjectUri"]) { + if( -not $ProjectUri -and $PSModuleInfo.PrivateData.PSData["ProjectUri"]) + { $ProjectUri = $PSModuleInfo.PrivateData.PSData.ProjectUri } - if ($PSModuleInfo.PrivateData.PSData["Prerelease"]) { + if ($PSModuleInfo.PrivateData.PSData["Prerelease"]) + { $psmoduleInfoPrereleaseString = $PSModuleInfo.PrivateData.PSData.Prerelease - if ($psmoduleInfoPrereleaseString -and $psmoduleInfoPrereleaseString.StartsWith("-")) { + if ($psmoduleInfoPrereleaseString -and $psmoduleInfoPrereleaseString.StartsWith("-")) + { $Version = [string]$Version + $psmoduleInfoPrereleaseString } - else { + else + { $Version = [string]$Version + "-" + $psmoduleInfoPrereleaseString } } - if ($PSModuleInfo.PrivateData.PSData["RequireLicenseAcceptance"]) { + if($PSModuleInfo.PrivateData.PSData["RequireLicenseAcceptance"]) + { $requireLicenseAcceptance = $PSModuleInfo.PrivateData.PSData.requireLicenseAcceptance.ToString().ToLower() - if ($requireLicenseAcceptance -eq "true") { - if ($FormatVersion -and ($FormatVersion.Major -lt $script:PSGetRequireLicenseAcceptanceFormatVersion.Major)) { - $message = $LocalizedData.requireLicenseAcceptanceNotSupported -f ($FormatVersion) + if($requireLicenseAcceptance -eq "true") + { + if($FormatVersion -and ($FormatVersion.Major -lt $script:PSGetRequireLicenseAcceptanceFormatVersion.Major)) + { + $message = $LocalizedData.requireLicenseAcceptanceNotSupported -f($FormatVersion) ThrowError -ExceptionName "System.InvalidOperationException" ` - -ExceptionMessage $message ` - -ErrorId "requireLicenseAcceptanceNotSupported" ` - -CallerPSCmdlet $PSCmdlet ` - -ErrorCategory InvalidData + -ExceptionMessage $message ` + -ErrorId "requireLicenseAcceptanceNotSupported" ` + -CallerPSCmdlet $PSCmdlet ` + -ErrorCategory InvalidData } - if (-not $LicenseUri) { + if(-not $LicenseUri) + { $message = $LocalizedData.LicenseUriNotSpecified ThrowError -ExceptionName "System.InvalidOperationException" ` -ExceptionMessage $message ` @@ -142,37 +156,42 @@ function Publish-PSArtifactUtility { } $LicenseFilePath = Join-PathUtility -Path $NugetPackageRoot -ChildPath 'License.txt' -PathType File - if (-not $LicenseFilePath -or -not (Test-Path -Path $LicenseFilePath -PathType Leaf)) { + if(-not $LicenseFilePath -or -not (Test-Path -Path $LicenseFilePath -PathType Leaf)) + { $message = $LocalizedData.LicenseTxtNotFound ThrowError -ExceptionName "System.InvalidOperationException" ` - -ExceptionMessage $message ` - -ErrorId "LicenseTxtNotFound" ` - -CallerPSCmdlet $PSCmdlet ` - -ErrorCategory InvalidData + -ExceptionMessage $message ` + -ErrorId "LicenseTxtNotFound" ` + -CallerPSCmdlet $PSCmdlet ` + -ErrorCategory InvalidData } - if ((Get-Content -LiteralPath $LicenseFilePath) -eq $null) { + if((Get-Content -LiteralPath $LicenseFilePath) -eq $null) + { $message = $LocalizedData.LicenseTxtEmpty ThrowError -ExceptionName "System.InvalidOperationException" ` - -ExceptionMessage $message ` - -ErrorId "LicenseTxtEmpty" ` - -CallerPSCmdlet $PSCmdlet ` - -ErrorCategory InvalidData + -ExceptionMessage $message ` + -ErrorId "LicenseTxtEmpty" ` + -CallerPSCmdlet $PSCmdlet ` + -ErrorCategory InvalidData } #RequireLicenseAcceptance is true, License uri and license.txt exist. Bump Up the FormatVersion - if (-not $FormatVersion) { + if(-not $FormatVersion) + { $FormatVersion = $script:CurrentPSGetFormatVersion } } - elseif ($requireLicenseAcceptance -ne "false") { + elseif($requireLicenseAcceptance -ne "false") + { $InvalidValueForRequireLicenseAcceptance = $LocalizedData.InvalidValueBoolean -f ($requireLicenseAcceptance, "requireLicenseAcceptance") Write-Warning -Message $InvalidValueForRequireLicenseAcceptance } } } } - else { + else + { $PSArtifactType = $script:PSArtifactTypeScript $Name = $PSScriptInfo.Name @@ -182,49 +201,60 @@ function Publish-PSArtifactUtility { $CompanyName = $PSScriptInfo.CompanyName $Copyright = $PSScriptInfo.Copyright - if ($PSScriptInfo.'Tags') { + if($PSScriptInfo.'Tags') + { $Tags = $PSScriptInfo.Tags } - if ($PSScriptInfo.'ReleaseNotes') { + if($PSScriptInfo.'ReleaseNotes') + { $ReleaseNotes = $PSScriptInfo.ReleaseNotes } - if ($PSScriptInfo.'LicenseUri') { + if($PSScriptInfo.'LicenseUri') + { $LicenseUri = $PSScriptInfo.LicenseUri } - if ($PSScriptInfo.'IconUri') { + if($PSScriptInfo.'IconUri') + { $IconUri = $PSScriptInfo.IconUri } - if ($PSScriptInfo.'ProjectUri') { + if($PSScriptInfo.'ProjectUri') + { $ProjectUri = $PSScriptInfo.ProjectUri } } # Add PSModule and PSGet format version tags - if (-not $Tags) { + if(-not $Tags) + { $Tags = @() } - if ($FormatVersion) { + if($FormatVersion) + { $Tags += "$($script:PSGetFormatVersion)_$FormatVersion" } $DependentModuleDetails = @() - if ($PSScriptInfo) { + if($PSScriptInfo) + { $Tags += "PSScript" - if ($PSScriptInfo.DefinedCommands) { - if ($PSScriptInfo.DefinedFunctions) { + if($PSScriptInfo.DefinedCommands) + { + if($PSScriptInfo.DefinedFunctions) + { $Tags += "$($script:Includes)_Function" $Tags += $PSScriptInfo.DefinedFunctions | Microsoft.PowerShell.Core\ForEach-Object { "$($script:Function)_$_" } } - if ($PSScriptInfo.DefinedWorkflows) { + if($PSScriptInfo.DefinedWorkflows) + { $Tags += "$($script:Includes)_Workflow" $Tags += $PSScriptInfo.DefinedWorkflows | Microsoft.PowerShell.Core\ForEach-Object { "$($script:Workflow)_$_" } } @@ -235,39 +265,46 @@ function Publish-PSArtifactUtility { # Populate the dependencies elements from RequiredModules and RequiredScripts # $ValidateAndGetScriptDependencies_Params = @{ - Repository = $Repository - DependentScriptInfo = $PSScriptInfo - CallerPSCmdlet = $PSCmdlet - Verbose = $VerbosePreference - Debug = $DebugPreference + Repository=$Repository + DependentScriptInfo=$PSScriptInfo + CallerPSCmdlet=$PSCmdlet + Verbose=$VerbosePreference + Debug=$DebugPreference } - if ($PSBoundParameters.ContainsKey('Credential')) { - $ValidateAndGetScriptDependencies_Params.Add('Credential', $Credential) + if ($PSBoundParameters.ContainsKey('Credential')) + { + $ValidateAndGetScriptDependencies_Params.Add('Credential',$Credential) } $DependentModuleDetails += ValidateAndGet-ScriptDependencies @ValidateAndGetScriptDependencies_Params } - else { + else + { $Tags += "PSModule" $ModuleManifestHashTable = Get-ManifestHashTable -Path $ManifestPath - if ($PSModuleInfo.ExportedCommands.Count) { - if ($PSModuleInfo.ExportedCmdlets.Count) { + if($PSModuleInfo.ExportedCommands.Count) + { + if($PSModuleInfo.ExportedCmdlets.Count) + { $Tags += "$($script:Includes)_Cmdlet" $Tags += $PSModuleInfo.ExportedCmdlets.Keys | Microsoft.PowerShell.Core\ForEach-Object { "$($script:Cmdlet)_$_" } #if CmdletsToExport field in manifest file is "*", we suggest the user to include all those cmdlets for best practice - if ($ModuleManifestHashTable -and $ModuleManifestHashTable.ContainsKey('CmdletsToExport') -and ($ModuleManifestHashTable.CmdletsToExport -eq "*")) { + if($ModuleManifestHashTable -and $ModuleManifestHashTable.ContainsKey('CmdletsToExport') -and ($ModuleManifestHashTable.CmdletsToExport -eq "*")) + { $WarningMessage = $LocalizedData.ShouldIncludeCmdletsToExport -f ($ManifestPath) Write-Warning -Message $WarningMessage } } - if ($PSModuleInfo.ExportedFunctions.Count) { + if($PSModuleInfo.ExportedFunctions.Count) + { $Tags += "$($script:Includes)_Function" $Tags += $PSModuleInfo.ExportedFunctions.Keys | Microsoft.PowerShell.Core\ForEach-Object { "$($script:Function)_$_" } - if ($ModuleManifestHashTable -and $ModuleManifestHashTable.ContainsKey('FunctionsToExport') -and ($ModuleManifestHashTable.FunctionsToExport -eq "*")) { + if($ModuleManifestHashTable -and $ModuleManifestHashTable.ContainsKey('FunctionsToExport') -and ($ModuleManifestHashTable.FunctionsToExport -eq "*")) + { $WarningMessage = $LocalizedData.ShouldIncludeFunctionsToExport -f ($ManifestPath) Write-Warning -Message $WarningMessage } @@ -277,23 +314,26 @@ function Publish-PSArtifactUtility { } $dscResourceNames = Get-ExportedDscResources -PSModuleInfo $PSModuleInfo - if ($dscResourceNames) { + if($dscResourceNames) + { $Tags += "$($script:Includes)_DscResource" $Tags += $dscResourceNames | Microsoft.PowerShell.Core\ForEach-Object { "$($script:DscResource)_$_" } #If DscResourcesToExport is commented out or "*" is used, we will write-warning - if ($ModuleManifestHashTable -and + if($ModuleManifestHashTable -and ($ModuleManifestHashTable.ContainsKey("DscResourcesToExport") -and - $ModuleManifestHashTable.DscResourcesToExport -eq "*") -or - -not $ModuleManifestHashTable.ContainsKey("DscResourcesToExport")) { + $ModuleManifestHashTable.DscResourcesToExport -eq "*") -or + -not $ModuleManifestHashTable.ContainsKey("DscResourcesToExport")) + { $WarningMessage = $LocalizedData.ShouldIncludeDscResourcesToExport -f ($ManifestPath) Write-Warning -Message $WarningMessage } } $RoleCapabilityNames = Get-AvailableRoleCapabilityName -PSModuleInfo $PSModuleInfo - if ($RoleCapabilityNames) { + if($RoleCapabilityNames) + { $Tags += "$($script:Includes)_RoleCapability" $Tags += $RoleCapabilityNames | Microsoft.PowerShell.Core\ForEach-Object { "$($script:RoleCapability)_$_" } @@ -302,22 +342,24 @@ function Publish-PSArtifactUtility { # Populate the module dependencies elements from RequiredModules and # NestedModules properties of the current PSModuleInfo $GetModuleDependencies_Params = @{ - PSModuleInfo = $PSModuleInfo - Repository = $Repository - CallerPSCmdlet = $PSCmdlet - Verbose = $VerbosePreference - Debug = $DebugPreference + PSModuleInfo=$PSModuleInfo + Repository=$Repository + CallerPSCmdlet=$PSCmdlet + Verbose=$VerbosePreference + Debug=$DebugPreference } - if ($PSBoundParameters.ContainsKey('Credential')) { - $GetModuleDependencies_Params.Add('Credential', $Credential) + if ($PSBoundParameters.ContainsKey('Credential')) + { + $GetModuleDependencies_Params.Add('Credential',$Credential) } $DependentModuleDetails = Get-ModuleDependencies @GetModuleDependencies_Params } $dependencies = @() - ForEach ($Dependency in $DependentModuleDetails) { + ForEach($Dependency in $DependentModuleDetails) + { $ModuleName = $Dependency.Name - $VersionString = "" + $VersionString = $null # Version format in NuSpec: # "[2.0]" --> (== 2.0) Required Version @@ -329,110 +371,277 @@ function Publish-PSArtifactUtility { # When both Minimum and Maximum versions are specified in the ModuleSpecification # [1.0,2.0] = 1.0 <= x <= 2.0 - if ($Dependency.Keys -Contains "RequiredVersion") { + if($Dependency.Keys -Contains "RequiredVersion") + { $VersionString = "[$($Dependency.RequiredVersion)]" } - elseif ($Dependency.Keys -Contains 'MinimumVersion' -and $Dependency.Keys -Contains 'MaximumVersion') { + elseif($Dependency.Keys -Contains 'MinimumVersion' -and $Dependency.Keys -Contains 'MaximumVersion') + { $VersionString = "[$($Dependency.MinimumVersion),$($Dependency.MaximumVersion)]" } - elseif ($Dependency.Keys -Contains 'MaximumVersion') { + elseif($Dependency.Keys -Contains 'MaximumVersion') + { $VersionString = "(,$($Dependency.MaximumVersion)]" } - elseif ($Dependency.Keys -Contains 'MinimumVersion') { + elseif($Dependency.Keys -Contains 'MinimumVersion') + { $VersionString = "$($Dependency.MinimumVersion)" } - $props = @{ - id = $ModuleName - version = $VersionString + if ([System.string]::IsNullOrWhiteSpace($VersionString)) + { + $dependencies += "" + } + else + { + $dependencies += "" } - - $dependencyObject = New-Object -TypeName PSCustomObject -Property $props - $dependencies += $dependencyObject - } - - $params = @{ - OutputPath = $NugetPackageRoot - Id = $Name - Version = $Version - Authors = $Author - Owners = $CompanyName - Description = $Description - ReleaseNotes = $ReleaseNotes - RequireLicenseAcceptance = ($requireLicenseAcceptance -eq $true) - Copyright = $Copyright - Tags = $Tags - LicenseUrl = $LicenseUri - ProjectUrl = $ProjectUri - IconUrl = $IconUri - Dependencies = $dependencies } - try { - $NuspecFullName = New-NuspecFile @params + # Populate the nuspec elements + $nuspec = @" + + + + $(Get-EscapedString -ElementValue "$Name") + $($Version) + $(Get-EscapedString -ElementValue "$Author") + $(Get-EscapedString -ElementValue "$CompanyName") + $(Get-EscapedString -ElementValue "$Description") + $(Get-EscapedString -ElementValue "$ReleaseNotes") + $($requireLicenseAcceptance.ToString()) + $(Get-EscapedString -ElementValue "$Copyright") + $(if($Tags){ Get-EscapedString -ElementValue ($Tags -join ' ')}) + $(if($LicenseUri){ + "$(Get-EscapedString -ElementValue "$LicenseUri")" + }) + $(if($ProjectUri){ + "$(Get-EscapedString -ElementValue "$ProjectUri")" + }) + $(if($IconUri){ + "$(Get-EscapedString -ElementValue "$IconUri")" + }) + + $dependencies + + + +"@ + +# When packaging we must build something. +# So, we are building an empty assembly called NotUsed, and discarding it. +$CsprojContent = @" + + + NotUsed + Temp project used for creating nupkg file. + $Name.nuspec + $NugetPackageRoot + netcoreapp2.0 + + +"@ + $NupkgPath = Microsoft.PowerShell.Management\Join-Path -Path $NugetPackageRoot -ChildPath "$Name.$Version.nupkg" + + $csprojBasePath = $null + if($script:DotnetCommandPath) { + $csprojBasePath = Microsoft.PowerShell.Management\Join-Path -Path $script:TempPath -ChildPath ([System.Guid]::NewGuid()) + $null = Microsoft.PowerShell.Management\New-Item -Path $csprojBasePath -ItemType Directory -Force -WhatIf:$false -Confirm:$false + $NuspecPath = Microsoft.PowerShell.Management\Join-Path -Path $csprojBasePath -ChildPath "$Name.nuspec" + $CsprojFilePath = Microsoft.PowerShell.Management\Join-Path -Path $csprojBasePath -ChildPath "$Name.csproj" } - catch { - Write-Error -Message "Failed to create nuspec file $_.Exception" -ErrorAction Stop + else { + $NuspecPath = Microsoft.PowerShell.Management\Join-Path -Path $NugetPackageRoot -ChildPath "$Name.nuspec" } - try { - if ($DotnetCommandPath) { - $NupkgFullName = New-NugetPackage -NuspecPath $NuspecFullName -NugetPackageRoot $NugetPackageRoot -UseDotnetCli -Verbose:$VerbosePreference + $tempErrorFile = $null + $tempOutputFile = $null + + try + { + # Remove existing nuspec and nupkg files + if($NupkgPath -and (Test-Path -Path $NupkgPath -PathType Leaf)) + { + Microsoft.PowerShell.Management\Remove-Item $NupkgPath -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue -Confirm:$false -WhatIf:$false } - elseif ($NuGetExePath) { - $NupkgFullName = New-NugetPackage -NuspecPath $NuspecFullName -NugetPackageRoot $NugetPackageRoot -NugetExePath $NuGetExePath -Verbose:$VerbosePreference + + if($NuspecPath -and (Test-Path -Path $NuspecPath -PathType Leaf)) + { + Microsoft.PowerShell.Management\Remove-Item $NuspecPath -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue -Confirm:$false -WhatIf:$false } - Write-Verbose -Message "Successfully created nuget package at $NupkgFullName" - } - catch { - if ($PSArtifactType -eq $script:PSArtifactTypeModule) { - $message = $LocalizedData.FailedToCreateCompressedModule -f ($_.Exception.message) - $errorId = "FailedToCreateCompressedModule" + Microsoft.PowerShell.Management\Set-Content -Value $nuspec -Path $NuspecPath -Force -Confirm:$false -WhatIf:$false -Encoding UTF8 + + # Create .nupkg file + if($script:DotnetCommandPath) { + Microsoft.PowerShell.Management\Set-Content -Value $CsprojContent -Path $CsprojFilePath -Force -Confirm:$false -WhatIf:$false + + $arguments = @('pack') + $arguments += $csprojBasePath + $arguments += @('--output',$NugetPackageRoot) + $arguments += "/p:StagingPath=$NugetPackageRoot" + $output = & $script:DotnetCommandPath $arguments + Write-Debug -Message "dotnet pack output: $output" } - else { - $message = $LocalizedData.FailedToCreateCompressedScript -f ($_.Exception.message) - $errorId = "FailedToCreateCompressedScript" + elseif($script:NuGetExePath) { + $output = & $script:NuGetExePath pack $NuspecPath -OutputDirectory $NugetPackageRoot } - Write-Error -Message $message -ErrorId $errorId -Category InvalidOperation -ErrorAction Stop - } + if(-not (Test-Path -Path $NupkgPath -PathType Leaf)) { + $SemanticVersionString = Get-NormalizedVersionString -Version $Version + $NupkgPath = Join-PathUtility -Path $NugetPackageRoot -ChildPath "$Name.$($SemanticVersionString).nupkg" -PathType File + } + + if($LASTEXITCODE -or -not $NupkgPath -or -not (Test-Path -Path $NupkgPath -PathType Leaf)) + { + if($PSArtifactType -eq $script:PSArtifactTypeModule) + { + $message = $LocalizedData.FailedToCreateCompressedModule -f ($output) + $errorId = "FailedToCreateCompressedModule" + } + else + { + $message = $LocalizedData.FailedToCreateCompressedScript -f ($output) + $errorId = "FailedToCreateCompressedScript" + } - try { - if ($DotnetCommandPath) { - Publish-NugetPackage -NupkgPath $NupkgFullName -Destination $Destination -NugetApiKey $NugetApiKey -UseDotnetCli -Verbose:$VerbosePreference + Write-Error -Message $message -ErrorId $errorId -Category InvalidOperation + return } - if ($NuGetExePath) { - Publish-NugetPackage -NupkgPath $NupkgFullName -Destination $Destination -NugetApiKey $NugetApiKey -NugetExePath $NuGetExePath -Verbose:$VerbosePreference + + # Publish the .nupkg to gallery + $tempErrorFile = Microsoft.PowerShell.Management\Join-Path -Path $nugetPackageRoot -ChildPath "TempPublishError.txt" + $tempOutputFile = Microsoft.PowerShell.Management\Join-Path -Path $nugetPackageRoot -ChildPath "TempPublishOutput.txt" + + $errorMsg = $null + $outputMsg = $null + $StartProcess_params = @{ + RedirectStandardError = $tempErrorFile + RedirectStandardOutput = $tempOutputFile + NoNewWindow = $true + Wait = $true + PassThru = $true } - if ($PSArtifactType -eq "Module") { - $message = $LocalizedData.PublishedSuccessfully -f ($Name, $Destination, $Name) + if($script:DotnetCommandPath) { + $StartProcess_params['FilePath'] = $script:DotnetCommandPath + + $ArgumentList = @('nuget') + $ArgumentList += 'push' + $ArgumentList += "`"$NupkgPath`"" + $ArgumentList += @('--source', "`"$($Destination.TrimEnd('\'))`"") + + if ($PSBoundParameters.Containskey('NugetApiKey')) { + $ArgumentList += @('--api-key', "`"$NugetApiKey`"") + } + } + elseif($script:NuGetExePath) { + $StartProcess_params['FilePath'] = $script:NuGetExePath + + $ArgumentList = @('push') + $ArgumentList += "`"$NupkgPath`"" + $ArgumentList += @('-source', "`"$($Destination.TrimEnd('\'))`"") + $ArgumentList += '-NonInteractive' + if ($PSBoundParameters.Containskey('NugetApiKey')) { + $ArgumentList += @('--api-key', "`"$NugetApiKey`"") + } + } + $StartProcess_params['ArgumentList'] = $ArgumentList + + if($script:IsCoreCLR -and -not $script:IsNanoServer) { + $StartProcess_params['WhatIf'] = $false + $StartProcess_params['Confirm'] = $false } - if ($PSArtifactType -eq "Script") { - $message = $LocalizedData.PublishedScriptSuccessfully -f ($Name, $Destination, $Name) + + $process = Microsoft.PowerShell.Management\Start-Process @StartProcess_params + + if(Test-Path -Path $tempErrorFile -PathType Leaf) { + $errorMsg = Microsoft.PowerShell.Management\Get-Content -Path $tempErrorFile -Raw + + if($errorMsg) { + Write-Verbose -Message $errorMsg + } + } + + if(Test-Path -Path $tempOutputFile -PathType Leaf) { + $outputMsg = Microsoft.PowerShell.Management\Get-Content -Path $tempOutputFile -Raw + + if($outputMsg) { + Write-Verbose -Message $outputMsg + } + } + + # The newer version of dotnet cli writes the error message into output stream instead of error stream + # Get the error message from output stream when ExitCode is non zero (error). + if($process -and $process.ExitCode -and -not $errorMsg -and $outputMsg) { + $errorMsg = $outputMsg } - Write-Verbose -Message $message + if(-not $process -or $process.ExitCode) + { + if(($NugetApiKey -eq 'VSTS') -and + ($errorMsg -match 'Cannot prompt for input in non-interactive mode.') ) + { + $errorMsg = $LocalizedData.RegisterVSTSFeedAsNuGetPackageSource -f ($Destination, $script:VSTSAuthenticatedFeedsDocUrl) + } + + if($errorMsg -match 'warn : No API Key was provided and no API Key could be found for *') + { + $errorMsg = $LocalizedData.NuGetApiKeyIsRequiredForNuGetBasedGalleryService -f ($Name, $Destination) + } + + if($PSArtifactType -eq $script:PSArtifactTypeModule) + { + $message = $LocalizedData.FailedToPublish -f ($Name,$errorMsg) + $errorId = "FailedToPublishTheModule" + } + else + { + $message = $LocalizedData.FailedToPublishScript -f ($Name,$errorMsg) + $errorId = "FailedToPublishTheScript" + } + + Write-Error -Message $message -ErrorId $errorId -Category InvalidOperation + } + else + { + if($PSArtifactType -eq $script:PSArtifactTypeModule) + { + $message = $LocalizedData.PublishedSuccessfully -f ($Name, $Destination, $Name) + } + else + { + $message = $LocalizedData.PublishedScriptSuccessfully -f ($Name, $Destination, $Name) + } + + Write-Verbose -Message $message + } } - catch { - if ( $NugetApiKey -eq "VSTS" -and ($_.Exception.Message -match "Cannot prompt for input in non-interactive mode.")) { - $message = $LocalizedData.RegisterVSTSFeedAsNuGetPackageSource -f ($Destination, $script:VSTSAuthenticatedFeedsDocUrl) + finally + { + if($NupkgPath -and (Test-Path -Path $NupkgPath -PathType Leaf)) + { + Microsoft.PowerShell.Management\Remove-Item $NupkgPath -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue -Confirm:$false -WhatIf:$false } - else { - $message = $_.Exception.message + + if($NuspecPath -and (Test-Path -Path $NuspecPath -PathType Leaf)) + { + Microsoft.PowerShell.Management\Remove-Item $NuspecPath -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue -Confirm:$false -WhatIf:$false } - if ($PSArtifactType -eq "Module") { - $errorMessage = $LocalizedData.FailedToPublish -f ($Name, $message) - $errorId = "FailedToPublishTheModule" + if($tempErrorFile -and (Test-Path -Path $tempErrorFile -PathType Leaf)) + { + Microsoft.PowerShell.Management\Remove-Item $tempErrorFile -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue -Confirm:$false -WhatIf:$false } - if ($PSArtifactType -eq "Script") { - $errorMessage = $LocalizedData.FailedToPublishScript -f ($Name, $message) - $errorId = "FailedToPublishTheScript" + if($tempOutputFile -and (Test-Path -Path $tempOutputFile -PathType Leaf)) + { + Microsoft.PowerShell.Management\Remove-Item $tempOutputFile -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue -Confirm:$false -WhatIf:$false } - Write-Error -Message $errorMessage -ErrorId $errorId -Category InvalidOperation -ErrorAction Stop + if($csprojBasePath -and (Test-Path -Path $csprojBasePath -PathType Container)) + { + Microsoft.PowerShell.Management\Remove-Item -Path $csprojBasePath -Recurse -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue -Confirm:$false -WhatIf:$false + } } -} +} \ No newline at end of file diff --git a/src/PowerShellGet/private/functions/Set-InstalledModulesVariable.ps1 b/src/PowerShellGet/private/functions/Set-InstalledModulesVariable.ps1 index 04a77f0d..9c358aac 100644 --- a/src/PowerShellGet/private/functions/Set-InstalledModulesVariable.ps1 +++ b/src/PowerShellGet/private/functions/Set-InstalledModulesVariable.ps1 @@ -11,6 +11,7 @@ function Set-InstalledModulesVariable $GetChildItemParams = @{ Path = $location Recurse = $true + Force = $true Filter = $script:PSGetItemInfoFileName ErrorAction = 'SilentlyContinue' WarningAction = 'SilentlyContinue' diff --git a/src/PowerShellGet/public/psgetfunctions/Publish-Module.ps1 b/src/PowerShellGet/public/psgetfunctions/Publish-Module.ps1 index 4a3d1f4b..5b9e2ac0 100644 --- a/src/PowerShellGet/public/psgetfunctions/Publish-Module.ps1 +++ b/src/PowerShellGet/public/psgetfunctions/Publish-Module.ps1 @@ -28,7 +28,6 @@ function Publish-Module { $RequiredVersion, [Parameter()] - [ValidateNotNullOrEmpty()] [string] $NuGetApiKey, @@ -70,13 +69,22 @@ function Publish-Module { [Uri] $ProjectUri, + [Parameter(ParameterSetName = "ModuleNameParameterSet")] + [ValidateNotNullOrEmpty()] + [string[]] + $Exclude, + [Parameter()] [switch] $Force, [Parameter(ParameterSetName = "ModuleNameParameterSet")] [switch] - $AllowPrerelease + $AllowPrerelease, + + [Parameter()] + [switch] + $SkipAutomaticTags ) Begin { @@ -137,8 +145,7 @@ function Publish-Module { if (-not $DestinationLocation -or (-not (Microsoft.PowerShell.Management\Test-Path $DestinationLocation) -and - -not (Test-WebUri -uri $DestinationLocation))) - { + -not (Test-WebUri -uri $DestinationLocation))) { $message = $LocalizedData.PSGalleryPublishLocationIsMissing -f ($Repository, $Repository) ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $message ` @@ -151,20 +158,6 @@ function Publish-Module { $message = $LocalizedData.PublishLocation -f ($DestinationLocation) Write-Verbose -Message $message - if (-not $NuGetApiKey.Trim()) { - if (Microsoft.PowerShell.Management\Test-Path -Path $DestinationLocation) { - $NuGetApiKey = "$(Get-Random)" - } - else { - $message = $LocalizedData.NuGetApiKeyIsRequiredForNuGetBasedGalleryService -f ($Repository, $DestinationLocation) - ThrowError -ExceptionName "System.ArgumentException" ` - -ExceptionMessage $message ` - -ErrorId "NuGetApiKeyIsRequiredForNuGetBasedGalleryService" ` - -CallerPSCmdlet $PSCmdlet ` - -ErrorCategory InvalidArgument - } - } - $providerName = Get-ProviderName -PSCustomObject $moduleSource if ($providerName -ne $script:NuGetProviderName) { $message = $LocalizedData.PublishModuleSupportsOnlyNuGetBasedPublishLocations -f ($moduleSource.PublishLocation, $Repository, $Repository) @@ -370,12 +363,12 @@ function Publish-Module { # This finds all the items without force (leaving out hidden files and dirs) then copies them Microsoft.PowerShell.Management\Get-ChildItem $Path -recurse | Microsoft.PowerShell.Management\Copy-Item -Force -Confirm:$false -WhatIf:$false -Destination { - if ($_.PSIsContainer) { - Join-Path $tempModulePathForFormatVersion $_.Parent.FullName.substring($path.length) - } - else { - join-path $tempModulePathForFormatVersion $_.FullName.Substring($path.Length) - } + if ($_.PSIsContainer) { + Join-Path $tempModulePathForFormatVersion $_.Parent.FullName.substring($path.length) + } + else { + join-path $tempModulePathForFormatVersion $_.FullName.Substring($path.Length) + } } try { @@ -543,7 +536,6 @@ function Publish-Module { $PublishPSArtifactUtility_Params = @{ PSModuleInfo = $moduleInfo ManifestPath = $manifestPath - NugetApiKey = $NuGetApiKey Destination = $DestinationLocation Repository = $Repository NugetPackageRoot = $tempModulePath @@ -561,6 +553,12 @@ function Publish-Module { if ($PSBoundParameters.Containskey('Credential')) { $PublishPSArtifactUtility_Params.Add('Credential', $Credential) } + if ($Exclude) { + $PublishPSArtifactUtility_Params.Add('Exclude', $Exclude) + } + if ($PSBoundParameters.Containskey('NugetApiKey')) { + $PublishPSArtifactUtility_Params.Add('NugetApiKey', $NuGetApiKey) + } Publish-PSArtifactUtility @PublishPSArtifactUtility_Params } } @@ -568,4 +566,4 @@ function Publish-Module { Microsoft.PowerShell.Management\Remove-Item $tempModulePath -Force -Recurse -ErrorAction Ignore -WarningAction SilentlyContinue -Confirm:$false -WhatIf:$false } } -} +} \ No newline at end of file diff --git a/src/PowerShellGet/public/psgetfunctions/Update-Module.ps1 b/src/PowerShellGet/public/psgetfunctions/Update-Module.ps1 index 8a24deb4..92adff7d 100644 --- a/src/PowerShellGet/public/psgetfunctions/Update-Module.ps1 +++ b/src/PowerShellGet/public/psgetfunctions/Update-Module.ps1 @@ -26,6 +26,11 @@ function Update-Module { [PSCredential] $Credential, + [Parameter()] + [ValidateSet("CurrentUser", "AllUsers")] + [string] + $Scope, + [Parameter(ValueFromPipelineByPropertyName = $true)] [ValidateNotNullOrEmpty()] [Uri] @@ -51,6 +56,17 @@ function Update-Module { Begin { Install-NuGetClientBinaries -CallerPSCmdlet $PSCmdlet -Proxy $Proxy -ProxyCredential $ProxyCredential + if ($Scope -eq "AllUsers" -and -not (Test-RunningAsElevated)) { + # Throw an error when Update-Module is used as a non-admin user and '-Scope AllUsers' + $message = $LocalizedData.UpdateModuleAdminPrivilegeRequiredForAllUsersScope -f @($script:programFilesModulesPath, $script:MyDocumentsModulesPath) + + ThrowError -ExceptionName "System.ArgumentException" ` + -ExceptionMessage $message ` + -ErrorId "UpdateModuleAdminPrivilegeRequiredForAllUsersScope" ` + -CallerPSCmdlet $PSCmdlet ` + -ErrorCategory InvalidArgument + } + # Module names already tried in the current pipeline $moduleNamesInPipeline = @() } @@ -135,7 +151,11 @@ function Update-Module { $PSBoundParameters["PackageManagementProvider"] = $providerName $PSBoundParameters["InstallUpdate"] = $true - $PSBoundParameters["Scope"] = Get-InstallationScope -PreviousInstallLocation $psgetItemInfo.InstalledLocation -CurrentUserPath $script:MyDocumentsModulesPath + if (-not $Scope) { + $Scope = Get-InstallationScope -PreviousInstallLocation $psgetItemInfo.InstalledLocation -CurrentUserPath $script:MyDocumentsModulesPath + } + + $PSBoundParameters["Scope"] = $Scope $sid = PackageManagement\Install-Package @PSBoundParameters } diff --git a/tests/PSGetRequireLicenseAcceptance.ps1 b/tests/PSGetRequireLicenseAcceptance.ps1 deleted file mode 100644 index 5d65e848..00000000 --- a/tests/PSGetRequireLicenseAcceptance.ps1 +++ /dev/null @@ -1,991 +0,0 @@ -<##################################################################################### - # File: PSGetRequireLicenseAcceptance.ps1 - # Tests for require license acceptance PSGet module functionality - # - # Copyright (c) Microsoft Corporation, 2014 - #####################################################################################> - -<# - Name: PowerShell.PSGet.PSGetRequireLicenseAcceptance - Description: Tests for Require License Acceptance functionality -#> - -function SuiteSetup { - Import-Module "$PSScriptRoot\PSGetTestUtils.psm1" -WarningAction SilentlyContinue - Import-Module "$PSScriptRoot\Asserts.psm1" -WarningAction SilentlyContinue - - $script:ProgramFilesModulesPath = Get-AllUsersModulesPath - $script:MyDocumentsModulesPath = Get-CurrentUserModulesPath - $script:PSGetLocalAppDataPath = Get-PSGetLocalAppDataPath - $script:TempPath = Get-TempPath - $script:PSGetRequireLicenseAcceptanceFormatVersion = "2.0" - - #Bootstrap NuGet binaries - Install-NuGetBinaries - - $script:PSGalleryRepoPath="$env:SystemDrive\PSGalleryRepo" - RemoveItem $script:PSGalleryRepoPath - $null = New-Item -Path $script:PSGalleryRepoPath -ItemType Directory -Force - - $script:moduleSourcesFilePath= Join-Path $script:PSGetLocalAppDataPath "PSRepositories.xml" - $script:moduleSourcesBackupFilePath = Join-Path $script:PSGetLocalAppDataPath "PSRepositories.xml_$(get-random)_backup" - if(Test-Path $script:moduleSourcesFilePath) - { - Rename-Item $script:moduleSourcesFilePath $script:moduleSourcesBackupFilePath -Force - } - - Set-PSGallerySourceLocation -Location $script:PSGalleryRepoPath -PublishLocation $script:PSGalleryRepoPath - - $modSource = Get-PSRepository -Name "PSGallery" - AssertEquals $modSource.SourceLocation $script:PSGalleryRepoPath "Test repository's SourceLocation is not set properly" - AssertEquals $modSource.PublishLocation $script:PSGalleryRepoPath "Test repository's PublishLocation is not set properly" - - $script:ApiKey="TestPSGalleryApiKey" - - # Create temp module to be published - $script:TempModulesPath="$env:LocalAppData\temp\PSGet_$(Get-Random)" - $null = New-Item -Path $script:TempModulesPath -ItemType Directory -Force - - $script:PublishModuleName = "RequireLicenseAcceptancePublishModule" - $script:PublishModuleBase = Join-Path $script:TempModulesPath $script:PublishModuleName - $null = New-Item -Path $script:PublishModuleBase -ItemType Directory -Force -} - -function SuiteCleanup { - if(Test-Path $script:moduleSourcesBackupFilePath) - { - Move-Item $script:moduleSourcesBackupFilePath $script:moduleSourcesFilePath -Force - } - else - { - RemoveItem $script:moduleSourcesFilePath - } - - # Import the PowerShellGet provider to reload the repositories. - $null = Import-PackageProvider -Name PowerShellGet -Force - - RemoveItem $script:PSGalleryRepoPath - RemoveItem $script:TempModulesPath -} - -Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.UpdateModuleManifest -Tags 'BVT','InnerLoop' { - BeforeAll { - SuiteSetup - } - - AfterAll { - SuiteCleanup - } - - AfterEach { - RemoveItem "$script:PSGalleryRepoPath\*" - RemoveItem "$script:PublishModuleBase\*" - } - - # Purpose: Validate Update-ModuleManifest sets RequireLicenseAcceptance flag - # - # Action: - # Update-ModuleManifest -RequireLicenseAcceptance - # Expected Result: Update-ModuleManifest should update the manifest with RequireLicenseAcceptance value - # - It UpdateModuleManifestWithRequireLicenseAcceptance { - New-ModuleManifest -Path "$script:PublishModuleBase\$script:PublishModuleName.psd1" - Update-ModuleManifest -Path "$script:PublishModuleBase\$script:PublishModuleName.psd1" -RequireLicenseAcceptance - $moduleInfo = Test-ModuleManifest -Path "$script:PublishModuleBase\$script:PublishModuleName.psd1" - $moduleInfo.PrivateData.PSData.RequireLicenseAcceptance | should be $true - } -} - -Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.Publish -Tags 'BVT','InnerLoop' { - if($PSEdition -eq 'Core') { - return - } - BeforeAll { - SuiteSetup - } - - AfterAll { - SuiteCleanup - } - - BeforeEach { - Set-Content "$script:PublishModuleBase\$script:PublishModuleName.psm1" -Value "function Get-$script:PublishModuleName { Get-Date }" - } - - AfterEach { - RemoveItem "$script:PSGalleryRepoPath\*" - RemoveItem "$script:ProgramFilesModulesPath\$script:PublishModuleName" - RemoveItem "$script:PublishModuleBase\*" - } - - # Purpose: Publish module that requires license acceptance - # - # Action: - # Update-ModuleManifest -RequireLicenseAcceptance - # Update-ModuleManifest -LicenseUri - # Add License.txt - # Publish-Module - # Expected Result: Update-ModuleManifest sets the RequireLicenseAcceptance flag. Publish-Module publishes the module - # - It "PublishModuleRequiresLicenseAcceptance" { - $version = "1.0" - New-ModuleManifest -Path "$script:PublishModuleBase\$script:PublishModuleName.psd1" -ModuleVersion $version -Description "$script:PublishModuleName module" -NestedModules "$script:PublishModuleName.psm1" - Update-ModuleManifest -Path "$script:PublishModuleBase\$script:PublishModuleName.psd1" -LicenseUri "http://$script:PublishModuleName.com/license" - Update-ModuleManifest -Path "$script:PublishModuleBase\$script:PublishModuleName.psd1" -RequireLicenseAcceptance - Set-Content "$script:PublishModuleBase\license.txt" -Value "LicenseTerms" - - Publish-Module -Path $script:PublishModuleBase -NuGetApiKey $script:ApiKey - $psgetItemInfo = Find-Module $script:PublishModuleName -RequiredVersion $version - $psgetItemInfo.AdditionalMetadata.requireLicenseAcceptance | should be "True" - $psgetItemInfo.PowerShellGetFormatVersion | should be $script:PSGetRequireLicenseAcceptanceFormatVersion - } - - # Purpose: Publish module without License.txt - # - # Action: - # Update-ModuleManifest -RequireLicenseAcceptance - # Update-ModuleManifest -LicenseUri - # Publish-Module - # Expected Result: It fails with LicenseTxtNotFound error - # - It "PublishModuleWithoutLicenseTxt" { - $version = "1.0" - New-ModuleManifest -Path "$script:PublishModuleBase\$script:PublishModuleName.psd1" -ModuleVersion $version -Description "$script:PublishModuleName module" -NestedModules "$script:PublishModuleName.psm1" - Update-ModuleManifest -Path "$script:PublishModuleBase\$script:PublishModuleName.psd1" -LicenseUri "http://$script:PublishModuleName.com/license" - Update-ModuleManifest -Path "$script:PublishModuleBase\$script:PublishModuleName.psd1" -RequireLicenseAcceptance - - AssertFullyQualifiedErrorIdEquals -scriptblock {Publish-Module -Path $script:PublishModuleBase -NuGetApiKey $script:ApiKey -WarningAction SilentlyContinue}` - -expectedFullyQualifiedErrorId 'LicenseTxtNotFound,Publish-PSArtifactUtility' - - } - - - # Purpose: Publish module without LicenseURI - # - # Action: - # Update-ModuleManifest -RequireLicenseAcceptance - # Add License.txt - # Publish-Module - # Expected Result: It fails with LicenseUriNotSpecified error - # - It "PublishModuleWithoutLicenseUri" { - $version = "1.0" - New-ModuleManifest -Path "$script:PublishModuleBase\$script:PublishModuleName.psd1" -ModuleVersion $version -Description "$script:PublishModuleName module" -NestedModules "$script:PublishModuleName.psm1" - Update-ModuleManifest -Path "$script:PublishModuleBase\$script:PublishModuleName.psd1" -RequireLicenseAcceptance - Set-Content "$script:PublishModuleBase\license.txt" -Value "LicenseTerms" - AssertFullyQualifiedErrorIdEquals -scriptblock {Publish-Module -Path $script:PublishModuleBase -NuGetApiKey $script:ApiKey -WarningAction SilentlyContinue}` - -expectedFullyQualifiedErrorId 'LicenseUriNotSpecified,Publish-PSArtifactUtility' - - } - - # Purpose: Publish module without setting requireLicenseAcceptance - # - # Action: - # Add LicenseUri - # Add License.txt - # Publish-Module - # Expected Result: Module is published with requirelicenseAcceptance set to False. - # - It "PublishModuleNoRequireLicenseAcceptance" { - $version = "1.0" - New-ModuleManifest -Path "$script:PublishModuleBase\$script:PublishModuleName.psd1" -ModuleVersion $version -Description "$script:PublishModuleName module" -NestedModules "$script:PublishModuleName.psm1" - Update-ModuleManifest -Path "$script:PublishModuleBase\$script:PublishModuleName.psd1" -LicenseUri "http://$script:PublishModuleName.com/license" - Set-Content "$script:PublishModuleBase\license.txt" -Value "LicenseTerms" - - Publish-Module -Path $script:PublishModuleBase -NuGetApiKey $script:ApiKey - $psgetItemInfo = Find-Module $script:PublishModuleName -RequiredVersion $version - $psgetItemInfo.AdditionalMetadata.requireLicenseAcceptance | should be "False" - } -} - -function InstallSuiteSetup { - Import-Module "$PSScriptRoot\PSGetTestUtils.psm1" -WarningAction SilentlyContinue - Import-Module "$PSScriptRoot\Asserts.psm1" -WarningAction SilentlyContinue - - $script:ProgramFilesModulesPath = Get-AllUsersModulesPath - $script:MyDocumentsModulesPath = Get-CurrentUserModulesPath - $script:PSGetLocalAppDataPath = Get-PSGetLocalAppDataPath - $script:TempPath = Get-TempPath - $null = New-Item -Path $script:MyDocumentsModulesPath -ItemType Directory -ErrorAction SilentlyContinue -WarningAction SilentlyContinue - #Bootstrap NuGet binaries - Install-NuGetBinaries - - $psgetModuleInfo = Import-Module PowerShellGet -Global -Force -Passthru - Import-LocalizedData script:LocalizedData -filename PSGet.Resource.psd1 -BaseDirectory $psgetModuleInfo.ModuleBase - - $script:moduleSourcesFilePath= Join-Path $script:PSGetLocalAppDataPath "PSRepositories.xml" - $script:moduleSourcesBackupFilePath = Join-Path $script:PSGetLocalAppDataPath "PSRepositories.xml_$(get-random)_backup" - if(Test-Path $script:moduleSourcesFilePath) - { - Rename-Item $script:moduleSourcesFilePath $script:moduleSourcesBackupFilePath -Force - } - - $Global:PSGallerySourceUri = '' - GetAndSet-PSGetTestGalleryDetails -SetPSGallery -PSGallerySourceUri ([REF]$Global:PSGallerySourceUri) -IsScriptSuite - - PSGetTestUtils\Uninstall-Module ModuleRequireLicenseAcceptance - Get-InstalledScript -Name ScriptRequireLicenseAcceptance -ErrorAction SilentlyContinue | Uninstall-Script -Force -} - -function InstallSuiteCleanup { - if(Test-Path $script:moduleSourcesBackupFilePath) - { - Move-Item $script:moduleSourcesBackupFilePath $script:moduleSourcesFilePath -Force - } - else - { - RemoveItem $script:moduleSourcesFilePath - } - - # Import the PowerShellGet provider to reload the repositories. - $null = Import-PackageProvider -Name PowerShellGet -Force -} - -Describe PowerShell.PSGet.PSGetRequireLicenseAcceptance.InstallSaveUpdate -Tags 'BVT','InnerLoop' { - - BeforeAll { - InstallSuiteSetup - } - - AfterAll { - InstallSuiteCleanup - } - - AfterEach { - Get-InstalledScript -Name ScriptRequireLicenseAcceptance -ErrorAction SilentlyContinue | Uninstall-Script -Force -ErrorAction SilentlyContinue - PSGetTestUtils\Uninstall-Module ModuleWithDependency - PSGetTestUtils\Uninstall-Module ModuleRequireLicenseAcceptance - } - - # Purpose: InstallModuleRequiringLicenseAcceptanceAndNoToPrompt - # - # Action: Install-Module ModuleRequireLicenseAcceptance - # - # Expected Result: module should not be installed after confirming NO - # - It "InstallModuleRequiringLicenseAcceptanceAndNoToPrompt" { - $outputPath = $script:TempPath - $guid = [system.guid]::newguid().tostring() - $outputFilePath = Join-Path $outputPath "$guid" - $runspace = CreateRunSpace $outputFilePath 1 - - # 2 is mapped to NO in ShouldProcess prompt - $Global:proxy.UI.ChoiceToMake=2 - $content = $null - - try - { - $result = ExecuteCommand $runspace 'Install-Module ModuleRequireLicenseAcceptance -Repository PSGallery' - } - finally - { - $fileName = "PromptForChoice-0.txt" - $path = join-path $outputFilePath $fileName - if(Test-Path $path) - { - $content = get-content $path - } - - CloseRunSpace $runspace - RemoveItem $outputFilePath - } - - $itemInfo = Find-Module ModuleRequireLicenseAcceptance -Repository PSGallery - - $installShouldProcessMessage = $script:LocalizedData.AcceptanceLicenseQuery -f ($itemInfo.Name) - Assert ($content -and ($content -match $installShouldProcessMessage)) "Install module confirm prompt is not working, Expected:$installShouldProcessMessage, Actual:$content" - - $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable - AssertNull $res "Install-Module should not install a module if Confirm is not accepted" - } ` - -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) - - # Purpose: InstallModuleRequiringLicenseAcceptanceAndYesToPrompt - # - # Action: Install-Module ModuleRequireLicenseAcceptance - # - # Expected Result: module should be installed after confirming YES - # - It "InstallModuleRequiringLicenseAcceptanceAndYesToPrompt" { - $outputPath = $script:TempPath - $guid = [system.guid]::newguid().tostring() - $outputFilePath = Join-Path $outputPath "$guid" - $runspace = CreateRunSpace $outputFilePath 1 - - # 0 is mapped to YES in ShouldProcess prompt - $Global:proxy.UI.ChoiceToMake=0 - $content = $null - - try - { - $result = ExecuteCommand $runspace 'Install-Module ModuleRequireLicenseAcceptance' - } - finally - { - $fileName = "PromptForChoice-0.txt" - $path = join-path $outputFilePath $fileName - if(Test-Path $path) - { - $content = get-content $path - } - - CloseRunSpace $runspace - RemoveItem $outputFilePath - } - - $itemInfo = Find-Module ModuleRequireLicenseAcceptance -Repository PSGallery - - $installShouldProcessMessage = $script:LocalizedData.AcceptanceLicenseQuery -f ($itemInfo.Name) - Assert ($content -and ($content -match $installShouldProcessMessage)) "Install module confirm prompt is not working, Expected:$installShouldProcessMessage, Actual:$content" - - $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable - Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance")) "Install-Module should install a module if Confirm is accepted" - } ` - -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) - - # Purpose: InstallModuleAcceptLicense - # - # Action: Install-Module ModuleRequireLicenseAcceptance -AcceptLicennse - # - # Expected Result: module is installed successfully - # - It "InstallModuleAcceptLicense" { - Install-Module ModuleRequireLicenseAcceptance -Repository PSGallery -AcceptLicense - $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable - Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance")) "Install-Module should install the module if -AcceptLicense is specified" - } - - - # Purpose: InstallModuleForce - # - # Action: Install-Module ModuleRequireLicenseAcceptance -Force - # - # Expected Result: module should fail to install with error ForceAcceptLicense - # - It "InstallModuleForce" { - AssertFullyQualifiedErrorIdEquals -scriptblock {Install-Module ModuleRequireLicenseAcceptance -Repository PSGallery -Force}` - -expectedFullyQualifiedErrorId 'ForceAcceptLicense,Install-Module' - } - - - # Purpose: InstallModuleWithDependencyAndYesToPrompt - # - # Action: Install-Module ModuleWithDependency - # - # Expected Result: User is prompted to accept license for dependant module. On yes, module is installed - # - It "InstallModuleWithDependencyAndYesToPrompt" { - $outputPath = $script:TempPath - $guid = [system.guid]::newguid().tostring() - $outputFilePath = Join-Path $outputPath "$guid" - $runspace = CreateRunSpace $outputFilePath 1 - - # 0 is mapped to YES in ShouldProcess prompt - $Global:proxy.UI.ChoiceToMake=0 - $content = $null - - try - { - $result = ExecuteCommand $runspace 'Install-Module ModuleWithDependency' - } - finally - { - $fileName = "PromptForChoice-0.txt" - $path = join-path $outputFilePath $fileName - if(Test-Path $path) - { - $content = get-content $path - } - - CloseRunSpace $runspace - RemoveItem $outputFilePath - } - - $itemInfo = Find-Module ModuleRequireLicenseAcceptance -Repository PSGallery - $installShouldProcessMessage = $script:LocalizedData.AcceptanceLicenseQuery -f ($itemInfo.Name) - Assert ($content -and ($content -match $installShouldProcessMessage)) "Install Module confirm prompt is not working, Expected:$installShouldProcessMessage, Actual:$content" - - $res = Get-Module ModuleWithDependency -ListAvailable - Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleWithDependency")) "Install-Module should install a module if Confirm is accepted" - - $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable - Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance")) "Install-Module should install a module if Confirm is accepted" - } ` - -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) - - # Purpose: InstallModuleWithDependencyAndNoToPrompt - # - # Action: Install-Module ModuleWithDependency - # - # Expected Result: User is prompted to accept license for dependant module. On No, neither of two modules is installed - # - It "InstallModuleWithDependencyAndNoToPrompt" { - $outputPath = $script:TempPath - $guid = [system.guid]::newguid().tostring() - $outputFilePath = Join-Path $outputPath "$guid" - $runspace = CreateRunSpace $outputFilePath 1 - - # 2 is mapped to NO in ShouldProcess prompt - $Global:proxy.UI.ChoiceToMake=2 - $content = $null - - try - { - $result = ExecuteCommand $runspace 'Install-Module ModuleWithDependency -Repository PSGallery' - } - finally - { - $fileName = "PromptForChoice-0.txt" - $path = join-path $outputFilePath $fileName - if(Test-Path $path) - { - $content = get-content $path - } - - CloseRunSpace $runspace - RemoveItem $outputFilePath - } - - $itemInfo = Find-Module ModuleRequireLicenseAcceptance -Repository PSGallery - - $installShouldProcessMessage = $script:LocalizedData.AcceptanceLicenseQuery -f ($itemInfo.Name) - Assert ($content -and ($content -match $installShouldProcessMessage)) "Install module confirm prompt is not working, Expected:$installShouldProcessMessage, Actual:$content" - - $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable - AssertNull $res "Install-Module should not install dependant module if Confirm is not accepted" - - $res = Get-Module ModuleWithDependency -ListAvailable - AssertNull $res "Install-Module should not install a module if Confirm is not accepted" - } ` - -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) - - # Purpose: InstallModuleWithDependencyAcceptLicense - # - # Action: Install-Module ModuleWithDependency -AcceptLicennse - # - # Expected Result: module is installed successfully - # - It "InstallModuleWithDependencyAcceptLicense" { - Install-Module ModuleWithDependency -AcceptLicense - - $res = Get-Module ModuleWithDependency -ListAvailable - Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleWithDependency")) "Install-Module should install the module if -AcceptLicense is specified" - - $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable - Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance")) "Install-Module should install the module if -AcceptLicense is specified" - } - - # Purpose: InstallScriptAndYesToPrompt - # - # Action: Install-Script ScriptRequireLicenseAcceptance - # - # Expected Result: Script and dependent module should be installed after confirming YES - # - It "InstallScriptAndYesToPrompt" { - $outputPath = $script:TempPath - $guid = [system.guid]::newguid().tostring() - $outputFilePath = Join-Path $outputPath "$guid" - $runspace = CreateRunSpace $outputFilePath 1 - - # 0 is mapped to YES in ShouldProcess prompt - $Global:proxy.UI.ChoiceToMake=0 - $content = $null - - try - { - $result = ExecuteCommand $runspace 'Install-Script ScriptRequireLicenseAcceptance' - } - finally - { - $fileName = "PromptForChoice-0.txt" - $path = join-path $outputFilePath $fileName - if(Test-Path $path) - { - $content = get-content $path - } - - CloseRunSpace $runspace - RemoveItem $outputFilePath - } - - $itemInfo = Find-Module ModuleRequireLicenseAcceptance -Repository PSGallery - $installShouldProcessMessage = $script:LocalizedData.AcceptanceLicenseQuery -f ($itemInfo.Name) - Assert ($content -and ($content -match $installShouldProcessMessage)) "Install script confirm prompt is not working, Expected:$installShouldProcessMessage, Actual:$content" - - $res = Get-InstalledScript ScriptRequireLicenseAcceptance - AssertEquals $res.Name "ScriptRequireLicenseAcceptance" "Install-Script failed to install $scriptName, $res" - - $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable - Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance")) "Install-Module should install a module if Confirm is accepted" - } ` - -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) - - - # Purpose: InstallScriptAndNoToPrompt - # - # Action: Install-Script ScriptRequireLicenseAcceptance - # - # Expected Result: Script and dependent module should NOT be installed after confirming NO - # - It "InstallScriptAndNoToPrompt" { - $outputPath = $script:TempPath - $guid = [system.guid]::newguid().tostring() - $outputFilePath = Join-Path $outputPath "$guid" - $runspace = CreateRunSpace $outputFilePath 1 - - # 2 is mapped to NO in ShouldProcess prompt - $Global:proxy.UI.ChoiceToMake=2 - $content = $null - - try - { - $result = ExecuteCommand $runspace 'Install-Script ScriptRequireLicenseAcceptance' - } - finally - { - $fileName = "PromptForChoice-0.txt" - $path = join-path $outputFilePath $fileName - if(Test-Path $path) - { - $content = get-content $path - } - - CloseRunSpace $runspace - RemoveItem $outputFilePath - } - - $itemInfo = Find-Module ModuleRequireLicenseAcceptance -Repository PSGallery - $installShouldProcessMessage = $script:LocalizedData.AcceptanceLicenseQuery -f ($itemInfo.Name) - Assert ($content -and ($content -match $installShouldProcessMessage)) "Install script confirm prompt is not working, Expected:$installShouldProcessMessage, Actual:$content" - - $res = Get-InstalledScript ScriptRequireLicenseAcceptance -ErrorAction SilentlyContinue - AssertNull $res "Script should not be installed" - - $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable - AssertNull $res "Dependant module should not be installed if Confirm is not accepted" - } ` - -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) - - - # Purpose: InstallScriptAcceptLicense - # - # Action: Install-Script ScriptRequireLicenseAcceptance -AcceptLicennse - # - # Expected Result: script and dependant module are installed successfully - # - It "InstallScriptAcceptLicense" { - Install-Script ScriptRequireLicenseAcceptance -AcceptLicense - - $res = Get-InstalledScript ScriptRequireLicenseAcceptance - AssertEquals $res.Name "ScriptRequireLicenseAcceptance" "Install-Script failed to install $scriptName, $res" - - $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable - Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance")) "Install-Module should install the module if -AcceptLicense is specified" - } - - # Purpose: SaveModuleRequiringLicenseAcceptanceAndNoToPrompt - # - # Action: Save-Module ModuleRequireLicenseAcceptance - # - # Expected Result: Module should not be saved after confirming NO - # - It "SaveModuleRequiringLicenseAcceptanceAndNoToPrompt" { - $outputPath = $script:TempPath - $guid = [system.guid]::newguid().tostring() - $outputFilePath = Join-Path $outputPath "$guid" - $runspace = CreateRunSpace $outputFilePath 1 - - # 2 is mapped to NO in ShouldProcess prompt - $Global:proxy.UI.ChoiceToMake=2 - $content = $null - - try - { - $result = ExecuteCommand $runspace "Save-Module ModuleRequireLicenseAcceptance -Path $script:MyDocumentsModulesPath -ErrorAction SilentlyContinue" - } - finally - { - $fileName = "PromptForChoice-0.txt" - $path = join-path $outputFilePath $fileName - if(Test-Path $path) - { - $content = get-content $path - } - - CloseRunSpace $runspace - RemoveItem $outputFilePath - } - - $itemInfo = Find-Module ModuleRequireLicenseAcceptance -Repository PSGallery - - $saveShouldProcessMessage = $script:LocalizedData.AcceptanceLicenseQuery -f ($itemInfo.Name) - Assert ($content -and ($content -match $saveShouldProcessMessage)) "Save module confirm prompt is not working, Expected:$installShouldProcessMessage, Actual:$content" - - $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable - AssertNull $res "Save-Module should not install a module if Confirm is not accepted" - } ` - -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) - - # Purpose: SaveModuleRequiringLicenseAcceptanceAndYesToPrompt - # - # Action: Save-Module ModuleRequireLicenseAcceptance - # - # Expected Result: module should be Saved after confirming YES - # - It "SaveModuleRequiringLicenseAcceptanceAndYesToPrompt" { - $outputPath = $script:TempPath - $guid = [system.guid]::newguid().tostring() - $outputFilePath = Join-Path $outputPath "$guid" - $runspace = CreateRunSpace $outputFilePath 1 - - # 0 is mapped to YES in ShouldProcess prompt - $Global:proxy.UI.ChoiceToMake=0 - $content = $null - - try - { - $result = ExecuteCommand $runspace "Save-Module ModuleRequireLicenseAcceptance -Path $script:MyDocumentsModulesPath" - } - finally - { - $fileName = "PromptForChoice-0.txt" - $path = join-path $outputFilePath $fileName - if(Test-Path $path) - { - $content = get-content $path - } - - CloseRunSpace $runspace - RemoveItem $outputFilePath - } - - $itemInfo = Find-Module ModuleRequireLicenseAcceptance -Repository PSGallery - - $saveShouldProcessMessage = $script:LocalizedData.AcceptanceLicenseQuery -f ($itemInfo.Name) - Assert ($content -and ($content -match $saveShouldProcessMessage)) "save module confirm prompt is not working, Expected:$installShouldProcessMessage, Actual:$content" - - $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable - Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance")) "save-Module should save a module if Confirm is accepted" - } ` - -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) - - # Purpose: SaveModuleAcceptLicense - # - # Action: Save-Module ModuleRequireLicenseAcceptance -AcceptLicennse - # - # Expected Result: module is saved successfully - # - It "SaveModuleAcceptLicense" { - Save-Module ModuleRequireLicenseAcceptance -Repository PSGallery -AcceptLicense -Path $script:MyDocumentsModulesPath - $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable - Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance")) "Install-Module should install the module if -AcceptLicense is specified" - } - - # Purpose: SaveModuleForce - # - # Action: Save-Module ModuleRequireLicenseAcceptance -Force - # - # Expected Result: module should fail to save with error ForceAcceptLicense - # - It "SaveModuleForce" { - AssertFullyQualifiedErrorIdEquals -scriptblock {Save-Module ModuleRequireLicenseAcceptance -Repository PSGallery -Force -Path $script:MyDocumentsModulesPath -WarningAction SilentlyContinue}` - -expectedFullyQualifiedErrorId 'ForceAcceptLicense,Install-Module' - } - - # Purpose: SaveModuleWithDependencyAndYesToPrompt - # - # Action: Save-Module ModuleWithDependency - # - # Expected Result: User is prompted to accept license for dependant module. On yes, module is Saved - # - It "SaveModuleWithDependencyAndYesToPrompt" { - $outputPath = $script:TempPath - $guid = [system.guid]::newguid().tostring() - $outputFilePath = Join-Path $outputPath "$guid" - $runspace = CreateRunSpace $outputFilePath 1 - - # 0 is mapped to YES in ShouldProcess prompt - $Global:proxy.UI.ChoiceToMake=0 - $content = $null - - try - { - $result = ExecuteCommand $runspace "Save-Module ModuleWithDependency -Path $script:MyDocumentsModulesPath" - } - finally - { - $fileName = "PromptForChoice-0.txt" - $path = join-path $outputFilePath $fileName - if(Test-Path $path) - { - $content = get-content $path - } - - CloseRunSpace $runspace - RemoveItem $outputFilePath - } - - $itemInfo = Find-Module ModuleRequireLicenseAcceptance -Repository PSGallery - $SaveShouldProcessMessage = $script:LocalizedData.AcceptanceLicenseQuery -f ($itemInfo.Name) - Assert ($content -and ($content -match $SaveShouldProcessMessage)) "Save Module confirm prompt is not working, Expected:$installShouldProcessMessage, Actual:$content" - - $res = Get-Module ModuleWithDependency -ListAvailable - Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleWithDependency")) "Save-Module should Save a module if Confirm is accepted" - - $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable - Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance")) "Save-Module should Save a module if Confirm is accepted" - } ` - -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) - - # Purpose: SaveModuleWithDependencyAndNoToPrompt - # - # Action: Save-Module ModuleWithDependency - # - # Expected Result: User is prompted to accept license for dependant module. On No, neither of two modules is Saved - # - It "SaveModuleWithDependencyAndNoToPrompt" { - $outputPath = $script:TempPath - $guid = [system.guid]::newguid().tostring() - $outputFilePath = Join-Path $outputPath "$guid" - $runspace = CreateRunSpace $outputFilePath 1 - - # 2 is mapped to NO in ShouldProcess prompt - $Global:proxy.UI.ChoiceToMake=2 - $content = $null - - try - { - $result = ExecuteCommand $runspace "Save-Module ModuleWithDependency -Path $script:MyDocumentsModulesPath -ErrorAction SilentlyContinue" - } - finally - { - $fileName = "PromptForChoice-0.txt" - $path = join-path $outputFilePath $fileName - if(Test-Path $path) - { - $content = get-content $path - } - - CloseRunSpace $runspace - RemoveItem $outputFilePath - } - - $itemInfo = Find-Module ModuleRequireLicenseAcceptance -Repository PSGallery - - $saveShouldProcessMessage = $script:LocalizedData.AcceptanceLicenseQuery -f ($itemInfo.Name) - Assert ($content -and ($content -match $saveShouldProcessMessage)) "Save module confirm prompt is not working, Expected:$installShouldProcessMessage, Actual:$content" - - $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable - AssertNull $res "Save-Module should not save dependant module if Confirm is not accepted" - - $res = Get-Module ModuleWithDependency -ListAvailable - AssertNull $res "Save-Module should not install a module if Confirm is not accepted" - } ` - -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) - - - # Purpose: SaveModuleWithDependencyAcceptLicense - # - # Action: Save-Module ModuleWithDependency -AcceptLicennse - # - # Expected Result: module is installed successfully - # - It "SaveModuleWithDependencyAcceptLicense" { - Save-Module ModuleWithDependency -AcceptLicense -Path $script:MyDocumentsModulesPath - - $res = Get-Module ModuleWithDependency -ListAvailable - Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleWithDependency")) "Install-Module should install the module if -AcceptLicense is specified" - - $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable - Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance")) "Install-Module should install the module if -AcceptLicense is specified" - } - - # Purpose: SaveScriptAndYesToPrompt - # - # Action: Save-Script ScriptRequireLicenseAcceptance - # - # Expected Result: Script and dependent module should be installed after confirming YES - # - It "SaveScriptAndYesToPrompt" { - $outputPath = $script:TempPath - $guid = [system.guid]::newguid().tostring() - $outputFilePath = Join-Path $outputPath "$guid" - $runspace = CreateRunSpace $outputFilePath 1 - - # 0 is mapped to YES in ShouldProcess prompt - $Global:proxy.UI.ChoiceToMake=0 - $content = $null - - try - { - $result = ExecuteCommand $runspace "Save-Script ScriptRequireLicenseAcceptance -Path $script:MyDocumentsModulesPath" - } - finally - { - $fileName = "PromptForChoice-0.txt" - $path = join-path $outputFilePath $fileName - if(Test-Path $path) - { - $content = get-content $path - } - - CloseRunSpace $runspace - RemoveItem $outputFilePath - } - - $itemInfo = Find-Module ModuleRequireLicenseAcceptance -Repository PSGallery - $SaveShouldProcessMessage = $script:LocalizedData.AcceptanceLicenseQuery -f ($itemInfo.Name) - Assert ($content -and ($content -match $SaveShouldProcessMessage)) "Save script confirm prompt is not working, Expected:$installShouldProcessMessage, Actual:$content" - - - - if(-not (Test-Path -Path "$script:MyDocumentsModulesPath\ScriptRequireLicenseAcceptance.ps1" -PathType Leaf)) - { - Assert $false "Save-Script should save script $ScriptName" - } - - $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable - Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance")) "Save-Module should save a module if Confirm is accepted" - } ` - -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) - - # Purpose: SaveScriptAcceptLicense - # - # Action: Save-Script ScriptRequireLicenseAcceptance -AcceptLicennse - # - # Expected Result: script and dependant module are Saved successfully - # - It "SaveScriptAcceptLicense" { - Save-Script ScriptRequireLicenseAcceptance -AcceptLicense -Path $script:MyDocumentsModulesPath - - if(-not (Test-Path -Path "$script:MyDocumentsModulesPath\ScriptRequireLicenseAcceptance.ps1" -PathType Leaf)) - { - Assert $false "Save-Script should save script $ScriptName" - } - - $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable - Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance")) "Save-Module should Save the module if -AcceptLicense is specified" - } - - - # Purpose: UpdateModuleRequiringLicenseAcceptanceAndNoToPrompt - # - # Action: Update-Module ModuleRequireLicenseAcceptance - # - # Expected Result: Module should not be updated after confirming NO - # - It "UpdateModuleRequiringLicenseAcceptanceAndNoToPrompt" { - - Install-module ModuleRequireLicenseAcceptance -RequiredVersion 1.0 -AcceptLicense -Force - - $outputPath = $script:TempPath - $guid = [system.guid]::newguid().tostring() - $outputFilePath = Join-Path $outputPath "$guid" - $runspace = CreateRunSpace $outputFilePath 1 - - # 2 is mapped to NO in ShouldProcess prompt - $Global:proxy.UI.ChoiceToMake=2 - $content = $null - - try - { - $result = ExecuteCommand $runspace 'Update-Module ModuleRequireLicenseAcceptance' - } - finally - { - $fileName = "PromptForChoice-0.txt" - $path = join-path $outputFilePath $fileName - if(Test-Path $path) - { - $content = get-content $path - } - - CloseRunSpace $runspace - RemoveItem $outputFilePath - } - - $itemInfo = Find-Module ModuleRequireLicenseAcceptance -Repository PSGallery - - $updateShouldProcessMessage = $script:LocalizedData.AcceptanceLicenseQuery -f ($itemInfo.Name) - Assert ($content -and ($content -match $updateShouldProcessMessage)) "Update module confirm prompt is not working, Expected:$updateShouldProcessMessage, Actual:$content" - - - - $res = Get-Module ModuleRequireLicenseAcceptance -ListAvailable - Assert (($res.Count -eq 1) -and ($res.Name -eq "ModuleRequireLicenseAcceptance") -and ($res.Version -eq [Version]"1.0")) "Update-Module should not update the module if confirm is declined" - } ` - -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) - - - # Purpose: UpdateModuleRequiringLicenseAcceptanceAndYesToPrompt - # - # Action: Update-Module ModuleRequireLicenseAcceptance - # - # Expected Result: Module should be Updated after confirming YES - # - It "UpdateModuleRequiringLicenseAcceptanceAndYesToPrompt" { - - Install-module ModuleRequireLicenseAcceptance -RequiredVersion 1.0 -AcceptLicense -Force - - $outputPath = $script:TempPath - $guid = [system.guid]::newguid().tostring() - $outputFilePath = Join-Path $outputPath "$guid" - $runspace = CreateRunSpace $outputFilePath 1 - - # 0 is mapped to YES in ShouldProcess prompt - $Global:proxy.UI.ChoiceToMake=0 - $content = $null - - try - { - $result = ExecuteCommand $runspace 'Update-Module ModuleRequireLicenseAcceptance' - } - finally - { - $fileName = "PromptForChoice-0.txt" - $path = join-path $outputFilePath $fileName - if(Test-Path $path) - { - $content = get-content $path - } - - CloseRunSpace $runspace - RemoveItem $outputFilePath - } - - $itemInfo = Find-Module ModuleRequireLicenseAcceptance -Repository PSGallery - - $UpdateShouldProcessMessage = $script:LocalizedData.AcceptanceLicenseQuery -f ($itemInfo.Name) - Assert ($content -and ($content -match $UpdateShouldProcessMessage)) "Update module confirm prompt is not working, Expected:$UpdateShouldProcessMessage, Actual:$content" - - $res = Get-InstalledModule ModuleRequireLicenseAcceptance -RequiredVersion 2.0 - AssertNotNull $res "Update-Module should Update a module if Confirm is accepted" - } ` - -Skip:$(($PSEdition -eq 'Core') -or ([System.Environment]::OSVersion.Version -lt "6.2.9200.0") -or ($PSCulture -ne 'en-US')) - - - # Purpose: UpdateModuleAcceptLicnese - # - # Action: Update-Module ModuleRequireLicenseAcceptance -AcceptLicennse - # - # Expected Result: module is Updated successfully - # - It "UpdateModuleAcceptLicnese" { - Install-module ModuleRequireLicenseAcceptance -RequiredVersion 1.0 -AcceptLicense -Force - Update-Module ModuleRequireLicenseAcceptance -AcceptLicense - $res = Get-InstalledModule ModuleRequireLicenseAcceptance -RequiredVersion 2.0 - AssertNotNull $res "Update-Module should Update a module" - } - - # Purpose: UpdateModuleForce - # - # Action: Update-Module ModuleRequireLicenseAcceptance -Force - # - # Expected Result: module should fail to Update with error ForceAcceptLicense - # - It "UpdateModuleForce" { - Install-module ModuleRequireLicenseAcceptance -RequiredVersion 1.0 -AcceptLicense -Force - AssertFullyQualifiedErrorIdEquals -scriptblock {Update-Module ModuleRequireLicenseAcceptance -Force}` - -expectedFullyQualifiedErrorId 'ForceAcceptLicense,Update-Module' - } - } diff --git a/tools/build.psm1 b/tools/build.psm1 index f9fdb897..19369c98 100644 --- a/tools/build.psm1 +++ b/tools/build.psm1 @@ -131,7 +131,7 @@ function Install-PackageManagement { $null = Microsoft.PowerShell.Management\New-Item -Path $OneGetModulePath -Force -ItemType Directory Microsoft.PowerShell.Management\Copy-Item -Path "$($OneGetWithVersion.FullName)\*" -Destination "$OneGetModulePath\" -Recurse -Force - Get-Module -ListAvailable -Name $OneGetModuleName | Microsoft.PowerShell.Core\Where-Object {$_.Version -eq $OneGetVersion} + Get-Module -ListAvailable -Name $OneGetModuleName | Microsoft.PowerShell.Core\Where-Object { $_.Version -eq $OneGetVersion } } finally { Remove-Item -Path $TempModulePath -Recurse -Force @@ -425,11 +425,25 @@ function Publish-ModuleArtifacts { } function Install-PublishedModule { # function to install the merged module artifact from /dist into the module path. + Param ( + [switch]$LocalDevInstall + ) + $moduleFolder = Join-Path -Path $ArtifactRoot -ChildPath 'PowerShellGet' - $PowerShellGetModuleInfo = Test-ModuleManifest "$moduleFolder\PowerShellGet.psd1" -ErrorAction Ignore + $manifestFullName = Join-Path -Path $moduleFolder -ChildPath "PowerShellGet.psd1" -ErrorAction Ignore + $PowerShellGetModuleInfo = Test-ModuleManifest $manifestFullName $ModuleVersion = "$($PowerShellGetModuleInfo.Version)" $InstallLocation = Join-Path -Path $AllUsersModulesPath -ChildPath 'PowerShellGet' + if ($LocalDevInstall) { + Write-Verbose -Message "Local dev installation specified." + $versionUnderDevelopment = "$ModuleVersion.9999" + $rawManifest = Get-Content -Path $manifestFullName -Raw + $newContent = $rawManifest -replace " ModuleVersion = '$ModuleVersion'", " ModuleVersion = '$versionUnderDevelopment'" + Set-Content -Path $manifestFullName -Value $newContent + $ModuleVersion = $versionUnderDevelopment + } + if (($script:PowerShellEdition -eq 'Core') -or ($PSVersionTable.PSVersion -ge '5.0.0')) { $InstallLocation = Join-Path -Path $InstallLocation -ChildPath $ModuleVersion } @@ -439,6 +453,26 @@ function Install-PublishedModule { Write-Verbose -Message "Copied module artifacts from $moduleFolder merged module artifact to`n$InstallLocation" } +function Install-DevelopmentModule { + Update-ModuleManifestFunctions + Publish-ModuleArtifacts + Install-PublishedModule -LocalDevInstall +} + +function Uninstall-DevelopmentModule { + $manifestFullName = Join-Path -Path $ModuleRoot -ChildPath "PowerShellGet.psd1" -ErrorAction Ignore + $PowerShellGetModuleInfo = Test-ModuleManifest $manifestFullName + $ModuleVersion = "$($PowerShellGetModuleInfo.Version)" + $InstallLocation = Join-Path -Path $AllUsersModulesPath -ChildPath 'PowerShellGet' + $versionUnderDevelopment = "$ModuleVersion.9999" + + if (($script:PowerShellEdition -eq 'Core') -or ($PSVersionTable.PSVersion -ge '5.0.0')) { + $InstallLocation = Join-Path -Path $InstallLocation -ChildPath $versionUnderDevelopment + Remove-Item $InstallLocation -Recurse -Force + } + +} + <# .SYNOPSIS This function changes the folder location in the current session to