diff --git a/scripts/cli.ps1 b/scripts/cli.ps1 index 4fd7787..8b8dec9 100644 --- a/scripts/cli.ps1 +++ b/scripts/cli.ps1 @@ -119,10 +119,20 @@ Do { break } 4 { + Clear-Host + setFilesChoice + break + } + 5 { Clear-Host installProg "Uninstall" break } + 6 { + Clear-Host + refresh + break + } Default { } } @@ -135,6 +145,8 @@ Do { Write-Host "`t" Write-Host "`tCopied/Hardlinked Path: $(getConfigProperty "newGamePath" )" Write-Host "`t" + Write-Host "`t[Hardlink = 1, Copy = 2] : $(getConfigProperty "hardlinkOrCopy" )" + Write-Host "`t" Write-Host "`tBypass Prompts: $(getConfigProperty "bypassPrompts" )" Write-Host "`t" Write-Host "`tStandalone Python: $(getConfigProperty "standalonePython" )" @@ -145,7 +157,9 @@ Do { 1. Set Paths 2. Set Bypass Choice 3. Set Python Choice - 4. Uninstall Dependencies (Choco Packages only) + 4. Set Game File Choice + 5. Uninstall Dependencies (Choco Packages only) + 6. Refresh Environment (If Choco Packages are not detected) q. Return " $setConfigOption = Read-Host "Choose an option" diff --git a/scripts/functions.ps1 b/scripts/functions.ps1 index 189510c..c0a1fb6 100644 --- a/scripts/functions.ps1 +++ b/scripts/functions.ps1 @@ -7,15 +7,13 @@ $pstools = "https://download.sysinternals.com/files/PSTools.zip" $python = "https://www.python.org/ftp/python/3.11.8/python-3.11.8-embed-amd64.zip" $progsToInstall = New-Object System.Collections.Generic.List[System.Object] -$dateNow = $((Get-Date).ToString('yyyy.MM.dd_hh.mm.ss')) -$logfileName = "logfile_$dateNow.log" $powershellVersion = $host.Version.Major -$version = "1.5.20" +$version = "1.5.21" # Paths -$rootPath = $PSScriptRoot | Split-Path -$logFolderPath = Join-Path $rootPath 'logs' -$LogPath = Join-Path $logFolderPath $logfileName +$rootPath = getRootPath +$logFolderPath = getLogPath | Split-Path +$LogPath = getLogPath $sfsePath = Join-Path $rootPath 'sfse' $sfseBuildPath = (Join-Path $sfsePath 'build') $toolsPath = (Join-Path $rootPath 'tools') @@ -46,27 +44,27 @@ function installProg() { Switch ($name) { "git" { - writeToConsole "`n`t`tInstalling Git..." -logPath $LogPath + writeToConsole "`n`t`tInstalling Git..." -log Start-Process -Wait -WindowStyle Hidden -Verb RunAs $poweshellExe -ArgumentList "-command choco install git -y --force | Out-File $LogPath -Append -Encoding UTF8" Break } "cmake" { - writeToConsole "`n`t`tInstalling CMake..." -logPath $LogPath + writeToConsole "`n`t`tInstalling CMake..." -log Start-Process -Wait -WindowStyle Hidden -Verb RunAs $poweshellExe -ArgumentList "-command choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System' -y --force | Out-File $LogPath -Append -Encoding UTF8" Break } "python" { - writeToConsole "`n`t`tInstalling Python 3..." -logPath $LogPath + writeToConsole "`n`t`tInstalling Python 3..." -log Start-Process -Wait -WindowStyle Hidden -Verb RunAs $poweshellExe -ArgumentList "-command choco install python311 -y --force | Out-File $LogPath -Append -Encoding UTF8" Break } "compiler" { - writeToConsole "`n`t`tInstalling C++ Build Tools, This might take a while.." -logPath $LogPath + writeToConsole "`n`t`tInstalling C++ Build Tools, This might take a while.." -log Start-Process -Wait -WindowStyle Hidden -Verb RunAs $poweshellExe -ArgumentList "-command choco install visualstudio2019buildtools visualstudio2019-workload-vctools --passive -y --force | Out-File $LogPath -Append -Encoding UTF8" Break } "chocolatey" { - writeToConsole "`n`t`tInstalling chocolatey..." -logPath $LogPath + writeToConsole "`n`t`tInstalling chocolatey..." -log # Choco requires admin rights to install properly Start-Process -Wait -WindowStyle Hidden -Verb RunAs $poweshellExe -ArgumentList "-command @@ -79,7 +77,7 @@ function installProg() { Break } "uninstall" { - writeToConsole "`n`t`tUninstalling choco packages..." -logPath $LogPath + writeToConsole "`n`t`tUninstalling choco packages..." -log Start-Process -Wait -WindowStyle Hidden -Verb RunAs $poweshellExe -ArgumentList "-command choco uninstall git git.install cmake cmake.install python311 visualstudio2019buildtools visualstudio2019-workload-vctools --confirm | Out-File $LogPath -Append -Encoding UTF8" @@ -114,7 +112,7 @@ function checkCommand() { } catch [System.Management.Automation.CommandNotFoundException] { # If we're here command not found, so software probably not installed - logToFile $_.Exception $LogPath + logToFile $_.Exception $isCommand = $false } @@ -135,15 +133,15 @@ function checkForCompiler() { } catch { # Clean-up left over files from check if failed - if (fileExists $PSScriptRoot '__cmake_systeminformation') { + if (fileExists -Path $PSScriptRoot -FileName '__cmake_systeminformation') { Remove-Item '__cmake_systeminformation' -Recurse } if ($output) { - logToFile $output $LogPath + logToFile $output } - logToFile $_.Exception $LogPath + logToFile $_.Exception return $False } @@ -201,13 +199,13 @@ function askAndDownload() { function checkForBuildTools() { #Check if we already downloaded it if ($progsToInstall.contains("cmake")) { - writeToConsole "`n`t`t`t> Cmake not installed, cannot check for compiler..." -logPath $LogPath + writeToConsole "`n`t`t`t> Cmake not installed, cannot check for compiler..." -log return $false } - writeToConsole "`n`t`t`t> Checking for Compiler, this might take a sec..." -logPath $LogPath + writeToConsole "`n`t`t`t> Checking for Compiler, this might take a sec..." -log if (checkForCompiler) { - writeToConsole "`n`t`t`t> C++ compiler found" -logPath $LogPath + writeToConsole "`n`t`t`t> C++ compiler found" -log return $true } } @@ -220,21 +218,21 @@ function checkDependencies() { "`n`tChecking to ensure all prerequisites are met..." "`n`tVisit the links for more info on each software" - writeToConsole ("`n`t`tChocolatey [https://chocolatey.org/] ...." + (& { if (isInstalled "chocolatey") { "`tInstalled" } else { "`tNot Found"; $progsToInstall.Add("chocolatey") } })) -logPath $LogPath + writeToConsole ("`n`t`tChocolatey [https://chocolatey.org/] ...." + (& { if (isInstalled "chocolatey") { "`tInstalled" } else { "`tNot Found"; $progsToInstall.Add("chocolatey") } })) -log if (![System.Convert]::ToBoolean((getConfigProperty "standalonePython"))) { - writeToConsole ("`n`t`tPython [https://www.python.org/] ...." + (& { if (isInstalled "python") { "`tInstalled" } else { "`tNot Found"; $progsToInstall.Add("python") } })) -logPath $LogPath + writeToConsole ("`n`t`tPython [https://www.python.org/] ...." + (& { if (isInstalled "python") { "`tInstalled" } else { "`tNot Found"; $progsToInstall.Add("python") } })) -log } else { installStandalonePython - writeToConsole ("`n`t`tPython [https://www.python.org/] .... Installed [Using Standalone]") -logPath $LogPath + writeToConsole ("`n`t`tPython [https://www.python.org/] .... Installed [Using Standalone]") -log } - writeToConsole ("`n`t`tCMake [https://cmake.org/] ...." + (& { if (isInstalled "cmake") { "`tInstalled" } else { "`tNot Found"; $progsToInstall.Add("CMake") } })) -logPath $LogPath + writeToConsole ("`n`t`tCMake [https://cmake.org/] ...." + (& { if (isInstalled "cmake") { "`tInstalled" } else { "`tNot Found"; $progsToInstall.Add("CMake") } })) -log - writeToConsole ("`n`t`tGit [https://git-scm.com/] ...." + (& { if (isInstalled "git") { "`tInstalled" } else { "`tNot Found"; $progsToInstall.Add("Git") } })) -logPath $LogPath + writeToConsole ("`n`t`tGit [https://git-scm.com/] ...." + (& { if (isInstalled "git") { "`tInstalled" } else { "`tNot Found"; $progsToInstall.Add("Git") } })) -log - writeToConsole ("`n`t`tC++ Build Tools ...." + (& { if (checkForBuildTools) { "`tInstalled" } else { "`tNot Found"; $progsToInstall.Add("compiler") } })) -logPath $LogPath + writeToConsole ("`n`t`tC++ Build Tools ...." + (& { if (checkForBuildTools) { "`tInstalled" } else { "`tNot Found"; $progsToInstall.Add("compiler") } })) -log if (![System.Convert]::ToBoolean((getConfigProperty "bypassPrompts"))) { Pause @@ -242,7 +240,7 @@ function checkDependencies() { } function installStandalonePython() { - if (!(fileExists (Join-Path $pythonPath "python.exe"))) { + if (!(fileExists -Path $pythonPath -FileName "python.exe")) { try { $question = "`n`tPython has not been detected on your system, do you want to download a standalone version? [y/n]" askAndDownload -question $question -downloadURL $python -fileName "python.zip" -bypass ([System.Convert]::ToBoolean((getConfigProperty "bypassPrompts"))) @@ -257,8 +255,8 @@ function installStandalonePython() { } catch { - writeToConsole "`n`tFailed to download Python, exiting!" -logPath $LogPath - logToFile $_.Exception $LogPath + writeToConsole "`n`tFailed to download Python, exiting!" -log + logToFile $_.Exception Pause exit } @@ -271,7 +269,7 @@ function installMissing() { $chocoOnlyDep = $progsToInstall.contains("chocolatey") -and $progsToInstall.ToArray().Count -eq 1 if ($progsToInstall.ToArray().Count -eq 0 -or $chocoOnlyDep) { - writeToConsole "`n`t`tNothing to install, returning to menu..." -logPath $LogPath + writeToConsole "`n`t`tNothing to install, returning to menu..." -log Start-Sleep 5 } else { @@ -280,23 +278,19 @@ function installMissing() { if ($progsToInstall.contains("chocolatey") -and !$chocoOnlyDep) { $progsToInstall.Remove("chocolatey") installProg "chocolatey" - - # Import choco for refreshenv command - $env:ChocolateyInstall = Convert-Path "$((Get-Command choco).Path)\..\.." - Import-Module "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1" } foreach ($prog in $progsToInstall) { installProg $prog } - writeToConsole "`n`t`tRefreshing Environment" -logPath $LogPath + writeToConsole "`n`t`tRefreshing Environment" -log Start-Sleep 2 # We need to refresh the env to detect new installs - refreshenv + refresh - writeToConsole "`n`t`tRe-checking dependencies" -logPath $LogPath + writeToConsole "`n`t`tRe-checking dependencies" -log checkDependencies } } @@ -311,11 +305,11 @@ function cloneRepo() { try { # Delete SFSE if already preset if (fileExists $sfsePath) { - writeToConsole "`n`t`tSFSE already exists, removing first" -logPath $LogPath + writeToConsole "`n`t`tSFSE already exists, removing first" -log Remove-Item -Force -Recurse $sfsePath } - writeToConsole "`n`t`tCloning SFSE and Checking out CommitID!" -logPath $LogPath + writeToConsole "`n`t`tCloning SFSE and Checking out CommitID!" -log git clone https://github.com/gazzamc/sfse.git Set-Location "sfse" @@ -328,8 +322,8 @@ function cloneRepo() { } catch { # Catch exception to prevent script failure - writeToConsole "`n`t`tFailed trying to checkout SFSE" -logPath $LogPath - logToFile $_.Exception $LogPath + writeToConsole "`n`t`tFailed trying to checkout SFSE" -log + logToFile $_.Exception } } @@ -347,34 +341,33 @@ function buildRepo() { runProcessAndLog $poweshellExe $rootPath "-command cmake --build '$sfseBuildPath' --config Release" 60 Clear-Host - writeToConsole "`n`t`tBuild finished, verifying!" -logPath $LogPath + writeToConsole "`n`t`tBuild finished, verifying!" -log if (fileExists $sfseBuildPath) { - writeToConsole "`n`t`tSuccessfully built" -logPath $LogPath + writeToConsole "`n`t`tSuccessfully built" -log if (![System.Convert]::ToBoolean((getConfigProperty "bypassPrompts"))) { Pause } } else { - writeToConsole "`n`t`tCould not verify build, check manually!" -logPath $LogPath + writeToConsole "`n`t`tCould not verify build, check manually!" -log Pause } } catch { # Catch exception to prevent script failure - writeToConsole "`n`t`tError Building SFSE, check that you have C++ dev tools installed!" -logPath $LogPath - logToFile $_.Exception $LogPath + writeToConsole "`n`t`tError Building SFSE, check that you have C++ dev tools installed!" -log + logToFile -Content $_.Exception Pause } } - function moveSFSEFiles() { # Reset path Clear-Host Set-Location $rootPath $gamePath = getConfigProperty "newGamePath" - writeToConsole "`n`t`tCopying SFSE Files to $gamePath..." -logPath $LogPath + writeToConsole "`n`t`tCopying SFSE Files to $gamePath..." -log $gameVersion = getGameVersion $filesToCopy = "sfse_loader.exe", "sfse_$gameVersion.dll" @@ -389,10 +382,10 @@ function moveSFSEFiles() { # Check files exist foreach ($file in $filesToCopy) { if (Test-Path -Path $gamePath -Filter $file) { - writeToConsole "`n`t`t$file Successfully Copied!" -logPath $LogPath + writeToConsole "`n`t`t$file Successfully Copied!" -log } else { - writeToConsole "`n`t`tThere was an issue copying $file!" -logPath $LogPath + writeToConsole "`n`t`tThere was an issue copying $file!" -log } } @@ -404,13 +397,13 @@ function moveSFSEFiles() { } catch { if ($_.Exception.GetType().Name -eq "RuntimeException") { - writeToConsole "`n`t`tFiles not found, please run build before trying to copy" -logPath $LogPath + writeToConsole "`n`t`tFiles not found, please run build before trying to copy" -log } else { - writeToConsole "`n`t`tAn Error occured during the copying of files, check log for more details" -logPath $LogPath + writeToConsole "`n`t`tAn Error occured during the copying of files, check log for more details" -log } - logToFile $_.Exception $LogPath + logToFile $_.Exception Pause } } @@ -434,7 +427,7 @@ function patchFiles() { $pythonExe = Join-Path $pythonPath 'python.exe' } - writeToConsole "`n`tPatching SFSE" -logPath $LogPath + writeToConsole "`n`tPatching SFSE" -log # Update hex values & $pythonExe $updateArgs | Out-File $LogPath -Append -Encoding UTF8 @@ -449,18 +442,18 @@ function patchFiles() { $verifyPatch | Out-File $LogPath -Append -Encoding UTF8 if ($verifyPatch[-2].SubString(6, 18) -eq "All files matched!") { - writeToConsole "`n`t`tSuccessfully Patched SFSE" -logPath $LogPath + writeToConsole "`n`t`tSuccessfully Patched SFSE" -log if (![System.Convert]::ToBoolean((getConfigProperty "bypassPrompts"))) { Pause } } else { - writeToConsole "`n`t`tUnsuccessfully Patched SFSE, check log to see which files failed md5 comparison" -logPath $LogPath + writeToConsole "`n`t`tUnsuccessfully Patched SFSE, check log to see which files failed md5 comparison" -log Pause } } catch { - logToFile $_.Exception $LogPath + logToFile $_.Exception } } @@ -491,7 +484,7 @@ function checkSpaceReq() { Space Required: $([Math]::Round($folderSize / 1Gb, 2)) Gb Free Disk Space ($driveLetter): $([Math]::Round($space / 1Gb, 2)) Gb - " -logPath $LogPath + " -log Pause } } @@ -514,8 +507,8 @@ function checkForPStools() { } catch { - writeToConsole "`n`tFailed to download PSTools, exiting!" -logPath $LogPath - logToFile $_.Exception $LogPath + writeToConsole "`n`tFailed to download PSTools, exiting!" -log + logToFile $_.Exception Pause exit } @@ -539,13 +532,13 @@ function moveGameEXE() { checkForPStools try { - if (fileExists $newGamePath 'Starfield.exe') { + if (fileExists -Path $newGamePath -FileName 'Starfield.exe') { throw [System.Exception] "`n`tStarfield.exe was not copied as it already exists in $newGamePath!"; } # We can't copy directly from game folder so we need to move and copy back - if (fileExists $gamePath 'Starfield.exe') { - writeToConsole "`n`tCopying Starfield.exe to new game folder!" -logPath $LogPath + if (fileExists -Path $gamePath -FileName 'Starfield.exe') { + writeToConsole "`n`tCopying Starfield.exe to new game folder!" -log # Calling powershell 7 from within psexec.exe does not seem to work, leaving it as powershell for now # as it's built-in to windows it should not cause issues as it's being called with system permissions anyway @@ -555,7 +548,7 @@ function moveGameEXE() { # Check that permissions we're stripped from exe if (hasPermissions (Join-Path $newGamePath 'Starfield.exe') -checkVersionInfo) { - writeToConsole "`n`tStarfield.exe moved successfully!" -logPath $LogPath + writeToConsole "`n`tStarfield.exe moved successfully!" -log } else { throw [System.IO.Exception] "Starfield.exe permissions we're not removed, please try again or check docs for manual process" @@ -565,14 +558,14 @@ function moveGameEXE() { throw [System.IO.FileNotFoundException] "Starfield.exe cannot be found in game path $gamePath" } - if (fileExists $newGamePath 'Starfield.exe') { + if (fileExists -Path $newGamePath -FileName 'Starfield.exe') { Start-Process -Wait -Verb RunAs $psExecPath "-s -i -nobanner -accepteula powershell Copy-Item (Join-Path '$newGamePath' 'Starfield.exe') -Destination (Join-Path '$gamePath' 'Starfield.exe')" Start-Sleep -Seconds 5 # check exe was copied back to starfield install folder - if (fileExists $gamePath 'Starfield.exe') { - writeToConsole "`n`tCopy of Starfield.exe created in original folder!" -logPath $LogPath + if (fileExists -Path $gamePath -FileName 'Starfield.exe') { + writeToConsole "`n`tCopy of Starfield.exe created in original folder!" -log } Start-Sleep -Seconds 5 @@ -583,18 +576,18 @@ function moveGameEXE() { } catch { if ($_.Exception.GetType().Name -eq "InvalidOperationException") { - writeToConsole "`n`tCannot find PsExec.exe, please check that PSTools has been downloaded to the tools folder." -logPath $LogPath + writeToConsole "`n`tCannot find PsExec.exe, please check that PSTools has been downloaded to the tools folder." -log } elseif ($_.Exception.GetType().Name -eq "FileNotFoundException") { - writeToConsole "`n`tStarfield.exe cannot be found in the folder specified, check log for more information!" -logPath $LogPath + writeToConsole "`n`tStarfield.exe cannot be found in the folder specified, check log for more information!" -log } else { - writeToConsole "`n`tFailed to copy Starfield.exe correctly, check log for more information!" -logPath $LogPath + writeToConsole "`n`tFailed to copy Starfield.exe correctly, check log for more information!" -log $msg = $_.Exception writeToConsole "`n`t > $msg" } - logToFile $_.Exception.Message $LogPath + logToFile $_.Exception.Message Pause Clear-Host } @@ -602,16 +595,21 @@ function moveGameEXE() { function moveGameFiles() { Clear-Host - writeToConsole "`n`tMove/Hardlink Game Files.." -logPath $LogPath + writeToConsole "`n`tMove/Hardlink Game Files.." -log - $type = Read-Host -Prompt " - 1. Copy Files - 2. Hardlink Files (Does not work across drives) - q. Return - - Choose the type of operation" + $choice = getConfigProperty "hardlinkOrCopy" + if ($choice -ne $null) { + $type = $choice + } + else { + $type = Read-Host -Prompt " + 1. Copy Files + 2. Hardlink Files (Does not work across drives) + q. Return + Choose the type of operation" + } Clear-Host @@ -627,7 +625,7 @@ function moveGameFiles() { return } - writeToConsole "`n`tCopying files to new location!" -logPath $LogPath + writeToConsole "`n`tCopying files to new location!" -log # Copy over files ROBOCOPY $gamePath $newGamePath /E /XF (Join-Path $gamePath "Starfield.exe") /MIR /NDL /NJH /NJS | @@ -647,7 +645,7 @@ function moveGameFiles() { } elseif ($type -eq 2) { - writeToConsole "`n`tHardlinking files to new location!" -logPath $LogPath + writeToConsole "`n`tHardlinking files to new location!" -log try { Get-ChildItem -Path $gamePath | ForEach-Object { @@ -662,7 +660,7 @@ function moveGameFiles() { } } catch { - logToFile $_.Exception $LogPath + logToFile $_.Exception } } } @@ -676,7 +674,7 @@ function autoInstall() { # Check if dependencies are installed otherwise redirect user back to main menu if ($progsToInstall.ToArray().Count -gt 0 -and !$chocoOnlyDep) { Clear-Host - writeToConsole "`n`tMissing dependencies, install all dependencies before proceeding: [$progsToInstall]" -logPath $LogPath + writeToConsole "`n`tMissing dependencies, install all dependencies before proceeding: [$progsToInstall]" -log Pause return } @@ -801,6 +799,22 @@ function setPythonChoice() { } } +function setFilesChoice() { + Clear-Host + $question = "Hardlink (same drive as original) or Copy Game files? [1/2]" + $confirmation = Read-Host $question + while ($confirmation -ne "1" -and $confirmation -ne "2") { + $confirmation = Read-Host $question + } + + if ($confirmation -eq '1') { + setConfigProperty "hardlinkOrCopy" 1 + } + elseif ($confirmation -eq '2') { + setConfigProperty "hardlinkOrCopy" 2 + } +} + function welcomeScreen() { Clear-Host $title = (Get-Content -Raw "header.txt").Replace('x.x.x', $version).Replace('[at]', '@') @@ -826,6 +840,7 @@ function welcomeScreen() { setGamePaths setPythonChoice setBypassChoice + setFilesChoice } diff --git a/scripts/utils.Tests.ps1 b/scripts/utils.Tests.ps1 index 26c187c..913cd95 100644 --- a/scripts/utils.Tests.ps1 +++ b/scripts/utils.Tests.ps1 @@ -105,9 +105,9 @@ Describe "writeToConsole" { Get-Command writeToConsole | Should -HaveParameter bgcolor -Type String Get-Command writeToConsole | Should -HaveParameter bgcolor -Mandatory:$false } - It "should have an optional parameter named logPath" { - Get-Command writeToConsole | Should -HaveParameter logPath -Type String - Get-Command writeToConsole | Should -HaveParameter logPath -Mandatory:$false + It "should have an optional parameter named log" { + Get-Command writeToConsole | Should -HaveParameter log -Type switch + Get-Command writeToConsole | Should -HaveParameter log -Mandatory:$false } } @@ -117,11 +117,11 @@ Describe "writeToConsole" { Should -Invoke Write-Information -ModuleName utils -Times 1 } - It "should call Write-Information & logToFile when passing msg and logPath" { + It "should call Write-Information & logToFile when passing msg and log param" { #Add global variable for logpath $global:LogPath = '/path/' - writeToConsole -msg "test" -logPath '/fake/path' + writeToConsole -msg "test" -log Should -Invoke Write-Information -ModuleName utils -Times 1 Should -Invoke logToFile -ModuleName utils -Times 1 @@ -256,6 +256,9 @@ Describe "setConfigProperty" { $configJson = '{ "gamePath": "C:\\XboxGames\\Starfield\\Content" }' Mock -ModuleName utils -CommandName 'Get-Content' -MockWith { return $configJson } + Mock -ModuleName utils -CommandName 'ConvertFrom-Json' -MockWith { return @{ "gamePath" = "C:\\XboxGames\\Starfield\\Content" } } + Mock -ModuleName utils -CommandName 'ConvertTo-Json' -MockWith { return $configJson } + Mock -ModuleName utils -CommandName 'Add-Member' } It "should have a setConfigProperty function" { @@ -264,15 +267,37 @@ Describe "setConfigProperty" { Context "functionality" { It "should create a new config file, if it doesn't already exist and store the given prop/val" { - } + Mock -ModuleName utils -CommandName 'fileExists' -MockWith { return $False } + + setConfigProperty "key" "val" | - It "should replace the value of the propert if it already exists in the config" { + Should -Invoke Get-Content -ModuleName utils -Times 0 + Should -Invoke ConvertTo-Json -ModuleName utils -Times 1 + Should -Invoke Out-File -ModuleName utils -Times 1 } - It "should add the prop/value to the end of the file if it does not exist in the config" { + It "should extend the config file if it exists and key/val does not" { + Mock -ModuleName utils -CommandName 'fileExists' -MockWith { return $True } + + setConfigProperty "key" "val" | + + Should -Invoke Get-Content -ModuleName utils -Times 1 + Should -Invoke ConvertTo-Json -ModuleName utils -Times 1 + Should -Invoke ConvertFrom-Json -ModuleName utils -Times 1 + Should -Invoke Out-File -ModuleName utils -Times 1 + Should -Invoke Add-Member -ModuleName utils -Times 1 } - It "should log any errors encountered" { + It "should replace the value of the property if it already exists in the config" { + Mock -ModuleName utils -CommandName 'fileExists' -MockWith { return $True } + + setConfigProperty "gamePath" "C:\\XboxGames\\Starfield\\Content" | + + Should -Invoke Get-Content -ModuleName utils -Times 1 + Should -Invoke ConvertTo-Json -ModuleName utils -Times 1 + Should -Invoke ConvertFrom-Json -ModuleName utils -Times 1 + Should -Invoke Out-File -ModuleName utils -Times 1 + Should -Invoke Add-Member -ModuleName utils -Times 0 } } } \ No newline at end of file diff --git a/scripts/utils.psm1 b/scripts/utils.psm1 index 4d9babf..516fad4 100644 --- a/scripts/utils.psm1 +++ b/scripts/utils.psm1 @@ -2,6 +2,12 @@ $rootPath = $PSScriptRoot | Split-Path $configPath = (Join-Path $rootPath 'config.json') +# Log +$dateNow = $((Get-Date).ToString('yyyy.MM.dd_hh.mm.ss')) +$logfileName = "logfile_$dateNow.log" +$logFolderPath = Join-Path $rootPath 'logs' +$LogPath = Join-Path $logFolderPath $logfileName + function testPath() { param ( [Parameter(Mandatory)] @@ -11,6 +17,14 @@ function testPath() { return Test-Path -LiteralPath $path } +function getRootPath() { + return $rootPath +} + +function getLogPath() { + return $LogPath +} + function fileExists() { [CmdletBinding(DefaultParameterSetName = 'Path')] param ( @@ -18,7 +32,7 @@ function fileExists() { [Parameter(Mandatory, ParameterSetName = 'PathAll', Position = 0)] [string]$Path, - [Parameter(ParameterSetName = 'PathAll')] + [Parameter(ParameterSetName = 'PathAll', Position = 1)] [string]$FileName ) @@ -41,13 +55,10 @@ function logToFile() { [CmdletBinding(DefaultParameterSetName = 'log')] param ( [Parameter(Mandatory, ParameterSetName = 'log', Position = 0)] - [String] $content, - - [Parameter(Mandatory, ParameterSetName = 'log', Position = 1)] - [String] $filePath + [String] $content ) - "$((Get-Date).ToString()) $content" | Out-File $filePath -Append -Encoding UTF8 + "$((Get-Date).ToString()) $content" | Out-File $LogPath -Append -Encoding UTF8 } function writeToConsole() { @@ -72,7 +83,7 @@ function writeToConsole() { [String] $bgcolor, [Parameter(Mandatory, ParameterSetName = 'Message-Log')] - [String] $logPath + [switch] $log ) if ($type) { @@ -86,9 +97,9 @@ function writeToConsole() { Write-Host $msg -ForegroundColor $color -BackgroundColor $bgcolor } - elseif ($logPath) { + elseif ($log) { Write-Information -MessageData $msg -InformationAction Continue - logToFile $msg $logPath + logToFile $msg } else { Write-Information -MessageData $msg -InformationAction Continue @@ -106,7 +117,7 @@ function getLatestFileName() { return $files[$latestVersionidx] } catch { - logToFile $_.Exception $LogPath + logToFile $_.Exception } } @@ -136,7 +147,7 @@ function getConfigProperty() { } } else { - logToFile "config not found - Path: $configPath" $LogPath + logToFile "config not found - Path: $configPath" return } } @@ -164,7 +175,7 @@ function setConfigProperty() { ConvertTo-Json $config -Depth 1 | Out-File $configPath -Force } catch { - logToFile $_.Exception $LogPath + logToFile $_.Exception } } @@ -211,9 +222,9 @@ function runProcessAndLog() { $p.WaitForExit() $stdout = $p.StandardOutput.ReadToEnd() $stderr = $p.StandardError.ReadToEnd() - logToFile "stdout: $stdout" $logPath - logToFile "stderr: $stderr" $logPath - logToFile ("exit code: " + $p.ExitCode) $logPath + logToFile -Content "stdout: $stdout" + logToFile -Content "stderr: $stderr" + logToFile -Content ("exit code: " + $p.ExitCode) } function hasPermissions() { @@ -250,4 +261,18 @@ function hasPermissions() { } return $false +} + +function refresh() { + # Check if choco is installed, if so use it's command otherwise fallback to manual refresh + try { + # Import choco for refreshenv command + $env:ChocolateyInstall = Convert-Path "$((Get-Command choco).Path)\..\.." + Import-Module "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1" + + refreshenv + } + catch { + $env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User") + } } \ No newline at end of file