Skip to content

Commit

Permalink
feat(install): rewrite posh script & opt-in marketplace install (spic…
Browse files Browse the repository at this point in the history
…etify#2663)

Co-authored-by: ririxi <[email protected]>
  • Loading branch information
SunsetTechuila and rxri authored Dec 27, 2023
1 parent c8abbf1 commit 5ebf432
Show file tree
Hide file tree
Showing 2 changed files with 221 additions and 177 deletions.
390 changes: 213 additions & 177 deletions install.ps1
Original file line number Diff line number Diff line change
@@ -1,177 +1,213 @@
# Copyright 2023 Spicetify. GPL license.
# Edited from project Denoland install script (https://github.com/denoland/deno_install)
param (
[string] $version
)

$PSMinVersion = 3

if ($v) {
$version = $v
}

#region Functions
function Write-Emphasized {
param (
[Parameter(Mandatory)]
[string] $Text
)

Write-Host -Object $Text -NoNewline -ForegroundColor "Cyan"
}

function Write-Log {
param (
[string] $ActionText,
[string[]] $Texts,
[boolean[]] $Emphasized
)

if (-not (Test-Path -Path $logFileDir)) {
New-Item -Path $logFileDir -ItemType File -Force | Out-Null
}

if (-not ($ActionText)) {
$FormattedActionText = "{0, -15}" -f $ActionText
Write-Host -Object $FormattedActionText -NoNewline
}

$logText = $FormattedActionText

for ($i = 0; $i -lt $Texts.Length -and $Texts.Length -eq $Emphasized.Length; $i++) {
if ($Emphasized.Get($i)) {
Write-Host -Object $Texts.Get($i) -NoNewline
}
else {
Write-Host -Object $Texts.Get($i) -NoNewline
}
$logText = $LogText + $Texts.Get($i)
}
$logText = "[{0}] {1}" -f (Get-Date -Format "HH:mm:ss yyyy-MM-dd"), $LogText
Add-Content -Path $logFileDir -Value $LogText -NoNewline
}

function Write-Done {
Write-Host -Object " > " -NoNewline
Write-Host -Object "OK" -ForegroundColor "Green"
Add-Content -Path $logFileDir -Value " > OK"
}

function Remove-OldPath {
$spicetifyOldDir = "${HOME}\spicetify-cli"
$_isInPath = $paths -contains $spicetifyOldDir -or $paths -contains "${spicetifyOldDir}\"

if ($_isInPath) {
Write-Log -ActionText "REMOVING" -Texts $spicetifyOldDir, " from Path" -Emphasized $true, $false
$replacedPath = $path.replace(";$spicetifyOldDir", "")
[Environment]::SetEnvironmentVariable("PATH", $replacedPath, $user)
$env:PATH = $env:PATH.replace(";$spicetifyOldDir", "")
Write-Done
}
}

function Move-ConfigFolder {
$spicetifyOldDirContent = "${HOME}\spicetify-cli\*"
$spicetifyOldDir = "${HOME}\spicetify-cli"
if (Test-Path -Path $spicetifyOldDir) {
Write-Log -ActionText "MIGRATING" -Texts $spicetifyOldDir, " into", $spicetifyDir -Emphasized $true, $false, $true
Copy-Item -Path $spicetifyOldDirContent -Destination $spicetifyDir -Force -Recurse
Write-Done
Write-Log -ActionText "REMOVING" -Texts $spicetifyOldDir -Emphasized $true
Remove-Item -LiteralPath $spicetifyOldDir -Force -Recurse
Write-Done
}
}
#endregion Functions

#region Main
if ($PSVersionTable.PSVersion.Major -ge $PSMinVersion) {
$ErrorActionPreference = "Stop"

# Enable TLS 1.2 since it is required for connections to GitHub.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

# Create %localappdata%\spicetify directory if it doesn't already exist
$spicetifyDir = "$env:LOCALAPPDATA\spicetify"
$logFileDir = "$spicetifyDir\install.log"

$currentUser = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
$isAdmin = $currentUser.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

if ($isAdmin) {
Write-Log -ActionText "WARNING" -Texts "The script was ran as Administrator which isn't recommended`n" -Emphasized $false
$Host.UI.RawUI.Flushinputbuffer()
$choice = $Host.UI.PromptForChoice("", "Do you want to abort the installation process to avoid any issues?", ("&Yes", "&No"), 0)
if ($choice -eq 0) {
Write-Log -ActionText "WARNING" -Texts "Exiting the script..." -Emphasized $false
exit
}
}

if (-not (Test-Path -Path $spicetifyDir)) {
Write-Log -ActionText "MAKING FOLDER" -Texts $spicetifyDir -Emphasized $true
Write-Done
}

if (-not $version) {
# Determine latest Spicetify release via GitHub API.
$latestReleaseUri = "https://api.github.com/repos/spicetify/spicetify-cli/releases/latest"
Write-Log -ActionText "DOWNLOADING" -Texts $latestReleaseUri -Emphasized $true
$latestReleaseJson = Invoke-WebRequest -Uri $latestReleaseUri -UseBasicParsing
Write-Done
$version = ($latestReleaseJson | ConvertFrom-Json).tag_name -replace "v", ""
}

# Migrate old spicetify folder to new location.
Move-ConfigFolder

# Download release.
$architecture = if ($env:PROCESSOR_ARCHITECTURE -eq "AMD64") { "x64" } else { "x32" }
$zipFile = "${spicetifyDir}\spicetify-${version}-windows-${architecture}.zip"
$downloadUri = "https://github.com/spicetify/spicetify-cli/releases/download/" +
"v${version}/spicetify-${version}-windows-${architecture}.zip"
Write-Log -ActionText "DOWNLOADING" -Texts $downloadUri -Emphasized $true
Invoke-WebRequest -Uri $downloadUri -UseBasicParsing -OutFile $zipFile
Write-Done

# Extract spicetify.exe and assets from .zip file.
Write-Log -ActionText "EXTRACTING" -Texts $zipFile, " into ", ${spicetifyDir} -Emphasized $true, $false, $true
# Using -Force to overwrite spicetify.exe and assets if it already exists
Expand-Archive -Path $zipFile -DestinationPath $spicetifyDir -Force
Write-Done

# Remove .zip file.
Write-Log -ActionText "REMOVING" -Texts $zipFile -Emphasized $true
Remove-Item -Path $zipFile
Write-Done

# Get Path environment variable for the current user.
$user = [EnvironmentVariableTarget]::User
$path = [Environment]::GetEnvironmentVariable("PATH", $user)

# Check whether spicetify dir is in the Path.
$paths = $path -split ";"

# Remove old spicetify folder from Path.
Remove-OldPath
$isInPath = $paths -contains $spicetifyDir -or $paths -contains "${spicetifyDir}\"

# Add Spicetify dir to PATH if it hasn't been added already.
if (-not $isInPath) {
Write-Log -ActionText "ADDING" -Texts $spicetifyDir, " to the ", "PATH", " environment variable..." -Emphasized $true, $false, $true, $false
[Environment]::SetEnvironmentVariable("PATH", "${path};${spicetifyDir}", $user)
# Add Spicetify to the PATH variable of the current terminal session
# so `spicetify` can be used immediately without restarting the terminal.
$env:PATH += ";${spicetifyDir}"
Write-Done
}

Write-Log -Texts "spicetify-cli was installed successfully." -Emphasized $false
Write-Done
Write-Log -Texts "Run ", "spicetify --help", " to get started.`n" -Emphasized $false, $true, $false
}
else {
Write-Log -Texts "`nYour Powershell version is lesser than ", "$PSMinVersion" -Emphasized $false, $true
Write-Log -Texts "`nPlease, update your Powershell downloading the ", "'Windows Management Framework'", " greater than ", "$PSMinVersion" -Emphasized $false, $true, $false, $true
}
#endregion Main
$ErrorActionPreference = 'Stop'
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

#region Variables
$spicetifyFolderPath = "$env:LOCALAPPDATA\spicetify"
$spicetifyOldFolderPath = "$HOME\spicetify-cli"
#endregion Variables

#region Functions
function Write-Success {
[CmdletBinding()]
param ()
process {
Write-Host -Object ' > OK' -ForegroundColor 'Green'
}
}

function Write-Unsuccess {
[CmdletBinding()]
param ()
process {
Write-Host -Object ' > ERROR' -ForegroundColor 'Red'
}
}

function Test-Admin {
[CmdletBinding()]
param ()
begin {
Write-Host -Object "Checking if the script wasn't ran as Administrator..." -NoNewline
}
process {
$currentUser = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
-not $currentUser.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
}

function Test-PowerShellVersion {
[CmdletBinding()]
param ()
begin {
$PSMinVersion = [version]'5.1'
}
process {
Write-Host -Object 'Checking if your PowerShell version is compatible...' -NoNewline
$PSVersionTable.PSVersion -ge $PSMinVersion
}
}

function Move-OldSpicetifyFolder {
[CmdletBinding()]
param ()
process {
if (Test-Path -Path $spicetifyOldFolderPath) {
Write-Host -Object 'Moving the old spicetify folder...' -NoNewline

Copy-Item -Path "$spicetifyOldFolderPath\*" -Destination $spicetifyFolderPath -Recurse -Force
Remove-Item -Path $spicetifyOldFolderPath -Recurse -Force
Write-Success
}
}
}

function Get-Spicetify {
[CmdletBinding()]
param ()
begin {
if ($env:PROCESSOR_ARCHITECTURE -eq 'AMD64') {
$architecture = 'x64'
}
else {
$architecture = 'x32'
}
if ($v) {
if ($v -match '^\d+\.\d+\.\d+$') {
$targetVersion = $v
}
else {
Write-Warning -Message "You have spicefied an invalid spicetify version: $v `nThe version must be in the following format: 1.2.3"

Pause
exit
}
}
else {
Write-Host -Object 'Fetching the latest spicetify version...' -NoNewline

$latestRelease = Invoke-RestMethod -Uri 'https://api.github.com/repos/spicetify/spicetify-cli/releases/latest'
$targetVersion = $latestRelease.tag_name -replace 'v', ''
Write-Success
}
$archivePath = "$env:TEMP\spicetify.zip"
}
process {
Write-Host -Object "Downloading spicetify v$targetVersion..." -NoNewline

$Parameters = @{
Uri = "https://github.com/spicetify/spicetify-cli/releases/download/v$targetVersion/spicetify-$targetVersion-windows-$architecture.zip"
UseBasicParsin = $true
OutFile = $archivePath
}
Invoke-WebRequest @Parameters
Write-Success
}
end {
$archivePath
}
}

function Add-SpicetifyToPath {
[CmdletBinding()]
param ()
begin {
Write-Host -Object 'Making spicetify available in the PATH...' -NoNewline

$user = [EnvironmentVariableTarget]::User
$path = [Environment]::GetEnvironmentVariable('PATH', $user)
}
process {
$path = $path -replace "$([regex]::Escape($spicetifyOldFolderPath))\\*;*", ''
if ($path -notlike "*$spicetifyFolderPath*") {
$path = "$path;$spicetifyFolderPath"
}
}
end {
[Environment]::SetEnvironmentVariable('PATH', $path, $user)
$env:PATH = $path
Write-Success
}
}

function Install-Spicetify {
[CmdletBinding()]
param ()
begin {
Write-Host -Object 'Installing spicetify...'

}
process {
$archivePath = Get-Spicetify
Write-Host -Object 'Extracting spicetify...' -NoNewline

Expand-Archive -Path $archivePath -DestinationPath $spicetifyFolderPath -Force
Write-Success
Add-SpicetifyToPath
}
end {
Remove-Item -Path $archivePath -Force
Write-Host -Object 'spicetify was successfully installed!' -ForegroundColor 'Green'

}
}
#endregion Functions

#region Main
#region Checks
if (-not (Test-PowerShellVersion)) {
Write-Unsuccess
Write-Warning -Message 'PowerShell 5.1 or higher is required to run this script'
Write-Warning -Message "You are running PowerShell $($PSVersionTable.PSVersion)"
Write-Host -Object 'PowerShell 5.1 install guide:'
Write-Host -Object 'https://learn.microsoft.com/skypeforbusiness/set-up-your-computer-for-windows-powershell/download-and-install-windows-powershell-5-1'
Write-Host -Object 'PowerShell 7 install guide:'
Write-Host -Object 'https://learn.microsoft.com/powershell/scripting/install/installing-powershell-on-windows'
Pause
exit
}
else {
Write-Success
}
if (-not (Test-Admin)) {
Write-Unsuccess
Write-Warning -Message "The script was ran as Administrator which isn't recommended"
$Host.UI.RawUI.Flushinputbuffer()
$choice = $Host.UI.PromptForChoice('', 'Do you want to abort the installation process to avoid any issues?', ('&Yes', '&No'), 0)
if ($choice -eq 0) {
Write-Host -Object 'spicetify installation aborted' -ForegroundColor 'Yellow'

Pause
exit
}
}
else {
Write-Success
}
#endregion Checks

#region Spicetify
Move-OldSpicetifyFolder
Install-Spicetify
Write-Host -Object "`nRun" -NoNewline
Write-Host -Object ' spicetify -h ' -NoNewline -ForegroundColor 'Cyan'
Write-Host -Object 'to get started'
#endregion Spicetify

#region Marketplace
$Host.UI.RawUI.Flushinputbuffer()
$choice = $Host.UI.PromptForChoice('', "`nDo you want to install Spicetify Marketplace?", ('&Yes', '&No'), 0)
if ($choice -eq 1) {
Write-Host -Object 'spicetify Marketplace installation aborted' -ForegroundColor 'Yellow'

}
else {
Write-Host -Object 'Starting the spicetify Marketplace installation script..'

$Parameters = @{
Uri = 'https://raw.githubusercontent.com/spicetify/spicetify-marketplace/main/resources/install.ps1'
UseBasicParsing = $true
}
Invoke-WebRequest @Parameters | Invoke-Expression
}
#endregion Marketplace
#endregion Main
Loading

0 comments on commit 5ebf432

Please sign in to comment.