Skip to content

Commit

Permalink
Microsoft.VSCode.DSC initial implementation (#57)
Browse files Browse the repository at this point in the history
  • Loading branch information
ryfu-msft authored Sep 13, 2024
1 parent dd9fe0f commit 8ad836a
Show file tree
Hide file tree
Showing 3 changed files with 248 additions and 0 deletions.
4 changes: 4 additions & 0 deletions pipelines/azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ extends:
displayName: 'Publish Pipeline GitDsc'
targetPath: $(Build.SourcesDirectory)\resources\GitDsc\
artifactName: GitDsc
- output: pipelineArtifact
displayName: 'Publish Pipeline Microsoft.VSCode.DSC'
targetPath: $(Build.SourcesDirectory)\resources\Microsoft.VSCode.DSC\
artifactName: Microsoft.VSCode.DSC

steps:
- checkout: self
Expand Down
24 changes: 24 additions & 0 deletions resources/Microsoft.VSCode.DSC/Microsoft.VSCode.DSC.psd1
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
@{
RootModule = 'Microsoft.VSCode.Dsc.psm1'
ModuleVersion = '0.1.0'
GUID = 'baf2c585-d931-4089-8500-93a5b8de1741'
Author = 'Microsoft Corporation'
CompanyName = 'Microsoft Corporation'
Copyright = '(c) Microsoft Corporation. All rights reserved.'
Description = 'DSC Resource for Visual Studio Code'
PowerShellVersion = '7.2'
DscResourcesToExport = @(
'VSCodeExtension'
)
PrivateData = @{
PSData = @{
# Tags applied to this module. These help with module discovery in online galleries.
Tags = @(
'PSDscResource_VSCodeExtension'
)

# Prerelease string of this module
Prerelease = 'alpha'
}
}
}
220 changes: 220 additions & 0 deletions resources/Microsoft.VSCode.DSC/Microsoft.VSCode.DSC.psm1
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

$ErrorActionPreference = "Stop"
Set-StrictMode -Version Latest

#region Functions
function Get-VSCodeCLIPath
{
# Currently only supports user/machine install for VSCode on Windows.
# TODO: Update this function to handle when VSCode is installed in portable mode or on macOS/Linux.
$codeCLIUserPath = "$env:LocalAppData\Programs\Microsoft VS Code\bin\code.cmd"
$codeCLIMachinePath = "$env:ProgramFiles\Microsoft VS Code\bin\code.cmd"

if (Test-Path -Path $codeCLIUserPath)
{
return $codeCLIUserPath
}
elseif (Test-Path -Path $codeCLIMachinePath)
{
return $codeCLIMachinePath
}
else
{
throw "VSCode is not installed."
}
}

function Install-VSCodeExtension
{
[CmdletBinding()]
param (
[Parameter(Mandatory, ValueFromPipelineByPropertyName)]
[string]$Name,
[Parameter(ValueFromPipelineByPropertyName)]
[string]$Version
)

begin
{
function Get-VSCodeExtensionInstallArgument
{
param([string]$Name, [string]$Version)

if ([string]::IsNullOrEmpty($Version))
{
return $Name
}

return @(
$Name
$Version
) -join '@'
}
}

process
{
$installArgument = Get-VSCodeExtensionInstallArgument @PSBoundParameters
Invoke-VSCode -Command "--install-extension $installArgument"
}
}

function Uninstall-VSCodeExtension
{
[CmdletBinding()]
param (
[Parameter(Mandatory, ValueFromPipelineByPropertyName)]
[string]$Name
)

Invoke-VSCode -Command "--uninstall-extension $($this.Name)"
}

function Invoke-VSCode
{
param (
[Parameter(Mandatory = $true)]
[string]$Command
)

try
{
Invoke-Expression "& `"$VSCodeCLIPath`" $Command"
}
catch
{
throw "Executing code.exe with {$Command} failed."
}
}
#endregion Functions

# Keeps the path of the code.exe CLI path.
$VSCodeCLIPath = Get-VSCodeCLIPath

#region DSCResources
[DSCResource()]
class VSCodeExtension
{
[DscProperty(Key)]
[string] $Name

[DscProperty()]
[string] $Version

[DscProperty()]
[bool] $Exist = $true

static [hashtable] $InstalledExtensions

static VSCodeExtension()
{
[VSCodeExtension]::GetInstalledExtensions()
}

static [VSCodeExtension[]] Export()
{
$extensionList = (Invoke-VSCode -Command "--list-extensions --show-versions") -Split [Environment]::NewLine

$results = [VSCodeExtension[]]::new($extensionList.length)

for ($i = 0; $i -lt $extensionList.length; $i++)
{
$extensionName, $extensionVersion = $extensionList[$i] -Split '@'
$results[$i] = [VSCodeExtension]@{
Name = $extensionName
Version = $extensionVersion
}
}

return $results
}

[VSCodeExtension] Get()
{
$currentState = [VSCodeExtension]::InstalledExtensions[$this.Name]
if ($null -ne $currentState)
{
return $currentState
}

return [VSCodeExtension]@{
Name = $this.Name
Version = $this.Version
Exist = $false
}
}

[bool] Test()
{
$currentState = $this.Get()
if ($currentState.Exist -ne $this.Exist)
{
return $false
}

if ($null -ne $this.Version -and $this.Version -ne $currentState.Version)
{
return $false
}

return $true
}

[void] Set()
{
if ($this.Test())
{
return
}

if ($this.Exist)
{
$this.Install($false)
}
else
{
$this.Uninstall($false)
}
}

#region VSCodeExtension helper functions
static [void] GetInstalledExtensions()
{
[VSCodeExtension]::InstalledExtensions = @{}
foreach ($extension in [VSCodeExtension]::Export())
{
[VSCodeExtension]::InstalledExtensions[$extension.Name] = $extension
}
}

[void] Install([bool] $preTest)
{
if ($preTest -and $this.Test())
{
return
}

Install-VSCodeExtension -Name $this.Name -Version $this.Version
[VSCodeExtension]::GetInstalledExtensions()
}

[void] Install()
{
$this.Install($true)
}

[void] Uninstall([bool] $preTest)
{
Uninstall-VSCodeExtension -Name $this.Name
[VSCodeExtension]::GetInstalledExtensions()
}

[void] Uninstall()
{
$this.Uninstall($true)
}
#endregion VSCodeExtension helper functions
}
#endregion DSCResources

0 comments on commit 8ad836a

Please sign in to comment.