GitDsc.psm1
# Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. using namespace System.Collections.Generic enum Ensure { Absent Present } # Assert once that Git is already installed on the system. Assert-Git #region DSCResources [DSCResource()] class GitClone { [DscProperty()] [Ensure]$Ensure = [Ensure]::Present [DscProperty(Key)] [string]$HttpsUrl [DscProperty()] [string]$RemoteName # The root directory where the project will be cloned to. (i.e. the directory where you expect to run `git clone`) [DscProperty(Mandatory)] [string]$RootDirectory [GitClone] Get() { $currentState = [GitClone]::new() $currentState.HttpsUrl = $this.HttpsUrl $currentState.RootDirectory = $this.RootDirectory $currentState.Ensure = [Ensure]::Absent $currentState.RemoteName = ($null -eq $this.RemoteName) ? "origin" : $this.RemoteName if (-not(Test-Path -Path $this.RootDirectory)) { return $currentState } Set-Location $this.RootDirectory $projectName = GetGitProjectName($this.HttpsUrl) $expectedDirectory = Join-Path -Path $this.RootDirectory -ChildPath $projectName if (Test-Path $expectedDirectory) { Set-Location -Path $expectedDirectory try { $gitRemoteValue = Invoke-GitRemote("get-url $($currentState.RemoteName)") if ($gitRemoteValue -like $this.HttpsUrl) { $currentState.Ensure = [Ensure]::Present } } catch { # Failed to execute `git remote`. Ensure state is `absent` } } return $currentState; } [bool] Test() { $currentState = $this.Get() return $currentState.Ensure -eq $this.Ensure } [void] Set() { if ($this.Ensure -eq [Ensure]::Absent) { throw "This resource does not support removing a cloned repository." } if (-not(Test-Path $this.RootDirectory)) { New-Item -ItemType Directory -Path $this.RootDirectory } Set-Location $this.RootDirectory Invoke-GitClone($this.HttpsUrl) } } [DSCResource()] class GitRemote { [DscProperty()] [Ensure]$Ensure = [Ensure]::Present [DscProperty(Key)] [string]$RemoteName [DscProperty(Key)] [string]$RemoteUrl # The root directory where the project will be cloned to. (i.e. the directory where you expect to run `git clone`) [DscProperty(Mandatory)] [string]$ProjectDirectory [GitRemote] Get() { $currentState = [GitRemote]::new() $currentState.RemoteName = $this.RemoteName $currentState.RemoteUrl = $this.RemoteUrl $currentState.ProjectDirectory = $this.ProjectDirectory if (-not(Test-Path -Path $this.ProjectDirectory)) { throw "Project directory does not exist." } Set-Location $this.ProjectDirectory try { $gitRemoteValue = Invoke-GitRemote("get-url $($this.RemoteName)") $currentState.Ensure = ($gitRemoteValue -like $this.RemoteUrl) ? [Ensure]::Present : [Ensure]::Absent } catch { $currentState.Ensure = [Ensure]::Absent } return $currentState } [bool] Test() { $currentState = $this.Get() return $currentState.Ensure -eq $this.Ensure } [void] Set() { Set-Location $this.ProjectDirectory if ($this.Ensure -eq [Ensure]::Present) { try { Invoke-GitRemote("add $($this.RemoteName) $($this.RemoteUrl)") } catch { throw "Failed to add remote repository." } } else { try { Invoke-GitRemote("remove $($this.RemoteName)") } catch { throw "Failed to remove remote repository." } } } } #endregion DSCResources #region Functions function Assert-Git { # Refresh session $path value before invoking 'git' $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") try { Invoke-Git -Command 'help' return } catch { throw "Git is not installed" } } function GetGitProjectName { param( [Parameter()] [string]$HttpsUrl ) $projectName = ($HttpsUrl.split('/')[-1]).split('.')[0] return $projectName } function Invoke-GitRemote { param( [Parameter()] [string]$Arguments ) $command = [List[string]]::new() $command.Add("remote") $command.Add($Arguments) return Invoke-Git -Command $command } function Invoke-GitClone { param( [Parameter()] [string]$Arguments ) $command = [List[string]]::new() $command.Add("clone") $command.Add($Arguments) return Invoke-Git -Command $command } function Invoke-Git { param ( [Parameter(Mandatory = $true)] [string]$Command ) return Invoke-Expression -Command "git $Command" } #endregion Functions |