Skip to content

Commit 28615c8

Browse files
authoredJun 10, 2019
Update git module (#37)
* dropping files * unified code * adding blank tests file * updated new cmdlet decumentation and readme * first update-module tests * advanced removal * unattended installation requires force * changelog * Linux path update * more diagnostics * export nef function * OS specific PSModulesPath split * get-module and get-installedmodule difference * silent installation for better test log * supported psm1 only modules * external help updated
1 parent a16c11c commit 28615c8

19 files changed

+491
-54
lines changed
 

‎.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
PesterTestResults.xml
1+
PesterTestResults.xml
2+
en-US/InstallModuleFromGit-help.xml

‎ChangeLog.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
Date: TBA
44

5-
## new features in 1.0.1
5+
## new features in 1.1.0
6+
- new command Update-GitModule which installs module only if local version exists and if older than remote
67

7-
## bug fixes in 1.0.1
8+
## bug fixes in 1.1.0
89

910
# v.1.0.1
1011

‎Docs/Get-GitModule.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ Cmdlet requires \`git\` client tool to work.
2424
It will download (\`git clone\`) specified repository to temporary directory and analyze it.
2525
By default, it will delete this temporary copy, but if needed, it can be kept.
2626

27-
Cmdlet searches for module manifest ( .psd1) file only.
28-
Modules with only .psm1 files are not supported at the moment.
27+
Cmdlet searches for module manifest ( .psd1) file or if that is not found for module (.psm1) file itself.
2928

3029
## EXAMPLES
3130

‎Docs/Install-GitModule.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ Cmdlet will actually download specified repository to user's default install dir
2727

2828
It does not support functionality \`-Scope AllUsers\`, but it is possible to specify \`-DestinationPath\` argument which will provide the same result.
2929

30-
Cmdlet searches for module manifest ( .psd1) file only.
31-
Modules with only .psm1 files are not supported at the moment.
30+
Cmdlet searches for module manifest ( .psd1) file or if that is not found for module (.psm1) file itself.
3231

3332
Note that this will not import module, only install it (the same as built-in cmdlet \`Install-Module\`).
3433
You can rely on PowerShell's automatic import of modules into user session when needed.

‎Docs/InstallModuleFromGit-help.xml

+164-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<maml:description>
1313
<maml:para>This cmdlet will check for existence of PowerShell module in given repository and return its version. You can also specify desired git branch.</maml:para>
1414
<maml:para>Cmdlet requires `git` client tool to work. It will download (`git clone`) specified repository to temporary directory and analyze it. By default, it will delete this temporary copy, but if needed, it can be kept.</maml:para>
15-
<maml:para>Cmdlet searches for module manifest ( .psd1) file only. Modules with only .psm1 files are not supported at the moment.</maml:para>
15+
<maml:para>Cmdlet searches for module manifest ( .psd1) file or if that is not found for module (.psm1) file itself.</maml:para>
1616
</maml:description>
1717
<command:syntax>
1818
<command:syntaxItem>
@@ -162,7 +162,7 @@ Git : https://github.com/iricigor/FIFA2018</dev:code>
162162
<maml:para>You can also specify desired git branch.</maml:para>
163163
<maml:para>Cmdlet internally uses `Get-GitModule` cmdlet, so it requires `git` client tool to work. Cmdlet will actually download specified repository to user's default install directory for PowerShell modules.</maml:para>
164164
<maml:para>It does not support functionality `-Scope AllUsers`, but it is possible to specify `-DestinationPath` argument which will provide the same result.</maml:para>
165-
<maml:para>Cmdlet searches for module manifest ( .psd1) file only. Modules with only .psm1 files are not supported at the moment.</maml:para>
165+
<maml:para>Cmdlet searches for module manifest ( .psd1) file or if that is not found for module (.psm1) file itself.</maml:para>
166166
<maml:para>Note that this will not import module, only install it (the same as built-in cmdlet `Install-Module`). You can rely on PowerShell's automatic import of modules into user session when needed.</maml:para>
167167
</maml:description>
168168
<command:syntax>
@@ -305,4 +305,166 @@ Git : https://github.com/iricigor/FIFA2018</dev:code>
305305
</command:examples>
306306
<command:relatedLinks />
307307
</command:command>
308+
<command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10" xmlns:MSHelp="http://msdn.microsoft.com/mshelp">
309+
<command:details>
310+
<command:name>Update-GitModule</command:name>
311+
<command:verb>Update</command:verb>
312+
<command:noun>GitModule</command:noun>
313+
<maml:description>
314+
<maml:para>This cmdlet updates previously installed PowerShell module specified by its git repository URL if repository contains newer version than installed one.</maml:para>
315+
</maml:description>
316+
</command:details>
317+
<maml:description>
318+
<maml:para>This cmdlet updates previously installed PowerShell module specified by its git repository URL if repository contains newer version than installed one.</maml:para>
319+
<maml:para>You can also specify desired git branch.</maml:para>
320+
<maml:para>Cmdlet internally uses `Get-GitModule` cmdlet, so it requires `git` client tool to work. Cmdlet will actually download specified repository to user's default install directory for PowerShell modules.</maml:para>
321+
<maml:para>Cmdlet searches for module manifest ( .psd1) file or if that is not found for module (.psm1) file itself.</maml:para>
322+
<maml:para>If you do not have the same module already installed, commandlet will throw an error.</maml:para>
323+
<maml:para>Note that this will not import module, only install it (the same as built-in cmdlet `Update-Module`). You can rely on PowerShell's automatic import of modules into user session when needed.</maml:para>
324+
</maml:description>
325+
<command:syntax>
326+
<command:syntaxItem>
327+
<maml:name>Update-GitModule</maml:name>
328+
<command:parameter required="true" variableLength="true" globbing="false" pipelineInput="True (ByPropertyName)" position="0" aliases="none">
329+
<maml:name>ProjectUri</maml:name>
330+
<maml:Description>
331+
<maml:para>Mandatory parameter specifying URL or the repository. Multiple values are supported. Parameter is passed to `git` client, so whatever works there is good value. For example, in GitHub URLs you can specify parameter both with or without `.git` at the end of URL.</maml:para>
332+
<maml:para>You can pass this parameter also via pipeline, for example via `Find-Module` built-in cmdlet.</maml:para>
333+
</maml:Description>
334+
<command:parameterValue required="true" variableLength="false">String[]</command:parameterValue>
335+
<dev:type>
336+
<maml:name>String[]</maml:name>
337+
<maml:uri />
338+
</dev:type>
339+
<dev:defaultValue>None</dev:defaultValue>
340+
</command:parameter>
341+
<command:parameter required="false" variableLength="true" globbing="false" pipelineInput="False" position="named" aliases="none">
342+
<maml:name>Branch</maml:name>
343+
<maml:Description>
344+
<maml:para>Optional parameter that specifies which branch should be cloned. If omitted, `master` branch will be used.</maml:para>
345+
</maml:Description>
346+
<command:parameterValue required="true" variableLength="false">String</command:parameterValue>
347+
<dev:type>
348+
<maml:name>String</maml:name>
349+
<maml:uri />
350+
</dev:type>
351+
<dev:defaultValue>None</dev:defaultValue>
352+
</command:parameter>
353+
<command:parameter required="false" variableLength="true" globbing="false" pipelineInput="False" position="named" aliases="none">
354+
<maml:name>DestinationPath</maml:name>
355+
<maml:Description>
356+
<maml:para>If you have a specific setup, you can override default install location with this parameter. As cmdlet always installs to user specific location, this can be useful to perform system wide installation (requires also elevated prompt).</maml:para>
357+
</maml:Description>
358+
<command:parameterValue required="true" variableLength="false">String</command:parameterValue>
359+
<dev:type>
360+
<maml:name>String</maml:name>
361+
<maml:uri />
362+
</dev:type>
363+
<dev:defaultValue>None</dev:defaultValue>
364+
</command:parameter>
365+
<command:parameter required="false" variableLength="true" globbing="false" pipelineInput="False" position="named" aliases="none">
366+
<maml:name>Force</maml:name>
367+
<maml:Description>
368+
<maml:para>If DestinationPath location is not empty, commandlet will not install newer version there. This behavior can be overridden with -Force switch.</maml:para>
369+
</maml:Description>
370+
<dev:type>
371+
<maml:name>SwitchParameter</maml:name>
372+
<maml:uri />
373+
</dev:type>
374+
<dev:defaultValue>False</dev:defaultValue>
375+
</command:parameter>
376+
</command:syntaxItem>
377+
</command:syntax>
378+
<command:parameters>
379+
<command:parameter required="false" variableLength="true" globbing="false" pipelineInput="False" position="named" aliases="none">
380+
<maml:name>Branch</maml:name>
381+
<maml:Description>
382+
<maml:para>Optional parameter that specifies which branch should be cloned. If omitted, `master` branch will be used.</maml:para>
383+
</maml:Description>
384+
<command:parameterValue required="true" variableLength="false">String</command:parameterValue>
385+
<dev:type>
386+
<maml:name>String</maml:name>
387+
<maml:uri />
388+
</dev:type>
389+
<dev:defaultValue>None</dev:defaultValue>
390+
</command:parameter>
391+
<command:parameter required="false" variableLength="true" globbing="false" pipelineInput="False" position="named" aliases="none">
392+
<maml:name>DestinationPath</maml:name>
393+
<maml:Description>
394+
<maml:para>If you have a specific setup, you can override default install location with this parameter. As cmdlet always installs to user specific location, this can be useful to perform system wide installation (requires also elevated prompt).</maml:para>
395+
</maml:Description>
396+
<command:parameterValue required="true" variableLength="false">String</command:parameterValue>
397+
<dev:type>
398+
<maml:name>String</maml:name>
399+
<maml:uri />
400+
</dev:type>
401+
<dev:defaultValue>None</dev:defaultValue>
402+
</command:parameter>
403+
<command:parameter required="false" variableLength="true" globbing="false" pipelineInput="False" position="named" aliases="none">
404+
<maml:name>Force</maml:name>
405+
<maml:Description>
406+
<maml:para>If DestinationPath location is not empty, commandlet will not install newer version there. This behavior can be overridden with -Force switch.</maml:para>
407+
</maml:Description>
408+
<command:parameterValue required="false" variableLength="false">SwitchParameter</command:parameterValue>
409+
<dev:type>
410+
<maml:name>SwitchParameter</maml:name>
411+
<maml:uri />
412+
</dev:type>
413+
<dev:defaultValue>False</dev:defaultValue>
414+
</command:parameter>
415+
<command:parameter required="true" variableLength="true" globbing="false" pipelineInput="True (ByPropertyName)" position="0" aliases="none">
416+
<maml:name>ProjectUri</maml:name>
417+
<maml:Description>
418+
<maml:para>Mandatory parameter specifying URL or the repository. Multiple values are supported. Parameter is passed to `git` client, so whatever works there is good value. For example, in GitHub URLs you can specify parameter both with or without `.git` at the end of URL.</maml:para>
419+
<maml:para>You can pass this parameter also via pipeline, for example via `Find-Module` built-in cmdlet.</maml:para>
420+
</maml:Description>
421+
<command:parameterValue required="true" variableLength="false">String[]</command:parameterValue>
422+
<dev:type>
423+
<maml:name>String[]</maml:name>
424+
<maml:uri />
425+
</dev:type>
426+
<dev:defaultValue>None</dev:defaultValue>
427+
</command:parameter>
428+
</command:parameters>
429+
<command:inputTypes>
430+
<command:inputType>
431+
<dev:type>
432+
<maml:name>System.String[]</maml:name>
433+
</dev:type>
434+
<maml:description>
435+
<maml:para></maml:para>
436+
</maml:description>
437+
</command:inputType>
438+
</command:inputTypes>
439+
<command:returnValues>
440+
<command:returnValue>
441+
<dev:type>
442+
<maml:name>System.Object</maml:name>
443+
</dev:type>
444+
<maml:description>
445+
<maml:para></maml:para>
446+
</maml:description>
447+
</command:returnValue>
448+
</command:returnValues>
449+
<maml:alertSet>
450+
<maml:alert>
451+
<maml:para></maml:para>
452+
</maml:alert>
453+
</maml:alertSet>
454+
<command:examples>
455+
<command:example>
456+
<maml:title>-------------------------- Example 1 --------------------------</maml:title>
457+
<dev:code>PS C:\&gt; Update-GitModule https://github.com/microsoft/SpeculationControl</dev:code>
458+
<dev:remarks>
459+
<maml:para>Updates the most downloadable PowerShell module directly from GitHub. If you do not have it installed, it will throw an error.</maml:para>
460+
</dev:remarks>
461+
</command:example>
462+
</command:examples>
463+
<command:relatedLinks>
464+
<maml:navigationLink>
465+
<maml:linkText>https://github.com/iricigor/InstallModuleFromGit/blob/master/Docs/Update-GitModule.md</maml:linkText>
466+
<maml:uri>https://github.com/iricigor/InstallModuleFromGit/blob/master/Docs/Update-GitModule.md</maml:uri>
467+
</maml:navigationLink>
468+
</command:relatedLinks>
469+
</command:command>
308470
</helpItems>

‎Docs/Update-GitModule.md

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
---
2+
external help file: InstallModuleFromGit-help.xml
3+
Module Name: InstallModuleFromGit
4+
online version: https://github.com/iricigor/InstallModuleFromGit/blob/master/Docs/Update-GitModule.md
5+
schema: 2.0.0
6+
---
7+
8+
# Update-GitModule
9+
10+
## SYNOPSIS
11+
This cmdlet updates previously installed PowerShell module specified by its git repository URL if repository contains newer version than installed one.
12+
13+
## SYNTAX
14+
15+
```
16+
Update-GitModule [-ProjectUri] <String[]> [-Branch <String>] [-DestinationPath <String>] [-Force]
17+
[<CommonParameters>]
18+
```
19+
20+
## DESCRIPTION
21+
22+
This cmdlet updates previously installed PowerShell module specified by its git repository URL if repository contains newer version than installed one.
23+
24+
You can also specify desired git branch.
25+
26+
Cmdlet internally uses \`Get-GitModule\` cmdlet, so it requires \`git\` client tool to work.
27+
Cmdlet will actually download specified repository to user's default install directory for PowerShell modules.
28+
29+
Cmdlet searches for module manifest ( .psd1) file or if that is not found for module (.psm1) file itself.
30+
31+
If you do not have the same module already installed, commandlet will throw an error.
32+
33+
Note that this will not import module, only install it (the same as built-in cmdlet \`Update-Module\`).
34+
You can rely on PowerShell's automatic import of modules into user session when needed.
35+
36+
## EXAMPLES
37+
38+
### Example 1
39+
```powershell
40+
PS C:\> Update-GitModule https://github.com/microsoft/SpeculationControl
41+
```
42+
43+
Updates the most downloadable PowerShell module directly from GitHub. If you do not have it installed, it will throw an error.
44+
45+
## PARAMETERS
46+
47+
### -Branch
48+
Optional parameter that specifies which branch should be cloned.
49+
If omitted, \`master\` branch will be used.
50+
51+
```yaml
52+
Type: String
53+
Parameter Sets: (All)
54+
Aliases:
55+
56+
Required: False
57+
Position: Named
58+
Default value: None
59+
Accept pipeline input: False
60+
Accept wildcard characters: False
61+
```
62+
63+
### -DestinationPath
64+
If you have a specific setup, you can override default install location with this parameter.
65+
As cmdlet always installs to user specific location, this can be useful to perform system wide installation (requires also elevated prompt).
66+
67+
```yaml
68+
Type: String
69+
Parameter Sets: (All)
70+
Aliases:
71+
72+
Required: False
73+
Position: Named
74+
Default value: None
75+
Accept pipeline input: False
76+
Accept wildcard characters: False
77+
```
78+
79+
### -Force
80+
If DestinationPath location is not empty, commandlet will not install newer version there.
81+
This behavior can be overridden with -Force switch.
82+
83+
```yaml
84+
Type: SwitchParameter
85+
Parameter Sets: (All)
86+
Aliases:
87+
88+
Required: False
89+
Position: Named
90+
Default value: None
91+
Accept pipeline input: False
92+
Accept wildcard characters: False
93+
```
94+
95+
### -ProjectUri
96+
Mandatory parameter specifying URL or the repository.
97+
Multiple values are supported.
98+
Parameter is passed to \`git\` client, so whatever works there is good value.
99+
For example, in GitHub URLs you can specify parameter both with or without \`.git\` at the end of URL.
100+
101+
You can pass this parameter also via pipeline, for example via \`Find-Module\` built-in cmdlet.
102+
103+
```yaml
104+
Type: String[]
105+
Parameter Sets: (All)
106+
Aliases:
107+
108+
Required: True
109+
Position: 0
110+
Default value: None
111+
Accept pipeline input: True (ByPropertyName)
112+
Accept wildcard characters: False
113+
```
114+
115+
### CommonParameters
116+
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
117+
118+
## INPUTS
119+
120+
### System.String[]
121+
122+
## OUTPUTS
123+
124+
### System.Object
125+
## NOTES
126+
127+
## RELATED LINKS
128+
129+
[https://github.com/iricigor/InstallModuleFromGit/blob/master/Docs/Update-GitModule.md](https://github.com/iricigor/InstallModuleFromGit/blob/master/Docs/Update-GitModule.md)
130+

‎InstallModuleFromGit.psd1

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ Description = 'Installs module from Git repository (i.e. GitHUb or Azure DevOps)
6969
# NestedModules = @()
7070

7171
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
72-
FunctionsToExport = @('Get-GitModule','Install-GitModule')
72+
FunctionsToExport = @('Get-GitModule','Install-GitModule','Update-GitModule')
7373

7474
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
7575
CmdletsToExport = @()

‎Private/Get-InstallPath.ps1

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ function Get-InstallPath {
22

33
# returns OS specific path for module installation, it support only -Scope CurrentUser
44
if ($IsLinux -or $IsOSX) {
5-
"$HOME/.local/share/powershell/Modules"
5+
#"$HOME/.local/share/powershell/Modules"
6+
# https://github.com/PowerShell/PowerShellGet/blob/d4dfebbbec4dfbe73392719a8a331541ed75d508/src/PowerShellGet/private/modulefile/PartOne.ps1#L71
7+
Join-Path (Split-Path -Path ([System.Management.Automation.Platform]::SelectProductNameForDirectory('USER_MODULES')) -Parent) 'Modules'
68
} else {
79
# https://github.com/PowerShell/PowerShellGet/blob/8004c304a2fa8ad32b92c6c2ba7efe116df3c862/src/PowerShellGet/private/modulefile/PartOne.ps1#L46
810
try {

‎Private/Install-ModuleInfo.ps1

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
function Install-ModuleInfo {
2+
3+
param(
4+
[PSObject]$ModuleInfo,
5+
[string]$DestinationPath,
6+
[switch]$Force
7+
)
8+
9+
# verify properties
10+
if (!$ModuleInfo.Root) {
11+
Write-Warning -Message "$FunctionName installing module with manifest not located in module root directory"
12+
}
13+
if (!$ModuleInfo.SameName) {
14+
Write-Warning -Message "$FunctionName installing module with module name not the same as its directory name"
15+
}
16+
17+
# check target directory
18+
$TargetDir = Join-Path (Join-Path $DestinationPath $ModuleInfo.Name) $ModuleInfo.Version
19+
if (!(Test-Path $TargetDir)) {
20+
New-Item $TargetDir -ItemType Directory -Force | Out-Null
21+
} elseif ((Get-ChildItem $TargetDir) -and (!$Force)) {
22+
Write-Error "$FunctionName cannot install into non-empty directory $TargetDir, use different -Destination or -Force to override it"
23+
continue
24+
}
25+
26+
# copy module
27+
Write-Verbose -Message "$(Get-Date -f T) installing module to $TargetDir"
28+
Copy-Item "$($ModuleInfo.LocalPath)/*" $TargetDir -Force -Recurse | Out-Null
29+
30+
# clean up
31+
$gitDir = Join-Path $TargetDir '.git'
32+
if (Test-Path $gitDir) {Remove-Item $gitDir -Recurse -Force}
33+
Remove-Item $ModuleInfo.LocalPath -Recurse -Force | Out-Null
34+
Write-Verbose -Message "$(Get-Date -f T) module $ModuleName installation completed"
35+
36+
# return value
37+
$ModuleInfo.LocalPath = $TargetDir
38+
$ModuleInfo
39+
}

‎Public/Get-GitModule.ps1

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ function Get-GitModule {
7575
Write-Verbose -Message "$(Get-Date -f T) not deleting temp copy"
7676
} else {
7777
Write-Verbose -Message "$(Get-Date -f T) deleting temp copy"
78-
Remove-Item $tempDir -Force -Recurse | Out-Null
78+
Remove-Item $tempDir -Force -Recurse -ea 0 | Out-Null
7979
}
8080

8181
if ($errorText) {

‎Public/Install-GitModule.ps1

+3-32
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ function Install-GitModule {
2727

2828
$tmpRoot = [System.IO.Path]::GetTempPath()
2929

30-
# TODO: Check if this is inside of $env:PSModulePath
31-
if ($DestinationPath -notin ($env:PSModulePath -split ';')) {
30+
$PSModulePaths = $env:PSModulePath -split (';:'[[int]($IsLinux -or $IsMacOS)])
31+
if ($DestinationPath -notin $PSModulePaths) {
3232
Write-Warning -Message "$FunctionName using path which is not in `$Env:PSModulePath ($DestinationPath)"
3333
}
3434

@@ -44,36 +44,7 @@ function Install-GitModule {
4444
$ModuleInfo = Get-GitModule -ProjectUri $P1 -KeepTempCopy
4545
if (!$ModuleInfo -or ($ModuleInfo.Count -gt 1)) {continue} # we have the error in get-gitmodule
4646

47-
# verify properties
48-
if (!$ModuleInfo.Root) {
49-
Write-Warning -Message "$FunctionName installing module with manifest not located in module root directory"
50-
}
51-
if (!$ModuleInfo.SameName) {
52-
Write-Warning -Message "$FunctionName installing module with module name not the same as its directory name"
53-
}
54-
55-
# check target directory
56-
$TargetDir = Join-Path (Join-Path $DestinationPath $ModuleInfo.Name) $ModuleInfo.Version
57-
if (!(Test-Path $TargetDir)) {
58-
New-Item $TargetDir -ItemType Directory -Force | Out-Null
59-
} elseif ((Get-ChildItem $TargetDir) -and (!$Force)) {
60-
Write-Error "$FunctionName cannot install into non-empty directory $TargetDir, use different -Destination or -Force to override it"
61-
continue
62-
}
63-
64-
# copy module
65-
Write-Verbose -Message "$(Get-Date -f T) installing module to $TargetDir"
66-
Copy-Item "$($ModuleInfo.LocalPath)/*" $TargetDir -Force -Recurse | Out-Null
67-
68-
# clean up
69-
$gitDir = Join-Path $TargetDir '.git'
70-
if (Test-Path $gitDir) {Remove-Item $gitDir -Recurse -Force}
71-
Remove-Item $ModuleInfo.LocalPath -Recurse -Force | Out-Null
72-
Write-Verbose -Message "$(Get-Date -f T) module $ModuleName installation completed"
73-
74-
# return value
75-
$ModuleInfo.LocalPath = $TargetDir
76-
$ModuleInfo
47+
Install-ModuleInfo -ModuleInfo $ModuleInfo -DestinationPath $DestinationPath -Force:$Force
7748
}
7849
}
7950

‎Public/Update-GitModule.ps1

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
function Update-GitModule {
2+
3+
[CmdletBinding(HelpUri='https://github.com/iricigor/InstallModuleFromGit/blob/master/Docs/Update-GitModule.md')]
4+
5+
param (
6+
7+
8+
[Parameter(Mandatory,ValueFromPipelineByPropertyName,Position=0)]
9+
[string[]]$ProjectUri,
10+
# https://github.com/dfinke/InstallModuleFromGitHub
11+
# https://github.com/iricigor/FIFA2018
12+
13+
[string]$Branch = "master",
14+
[string]$DestinationPath = (Get-InstallPath),
15+
[switch]$Force
16+
17+
)
18+
19+
BEGIN {
20+
$FunctionName = $MyInvocation.MyCommand.Name
21+
Write-Verbose -Message "$(Get-Date -f G) $FunctionName starting"
22+
23+
if (!(Test-Prerequisites)) {
24+
throw "$FunctionName prerequisites not met"
25+
# TODO: Add more details
26+
}
27+
28+
if ($env:AGENT_TEMPDIRECTORY) {
29+
$tmpRoot = $env:AGENT_TEMPDIRECTORY
30+
} else {
31+
$tmpRoot = [System.IO.Path]::GetTempPath()
32+
}
33+
34+
}
35+
36+
PROCESS {
37+
38+
foreach ($P1 in $ProjectUri) {
39+
40+
Write-Verbose -Message "$(Get-Date -f T) processing $P1"
41+
42+
$RemoteModuleInfo = Get-GitModule -ProjectUri $P1 -KeepTempCopy
43+
if (!$RemoteModuleInfo -or ($RemoteModuleInfo.Count -gt 1)) {continue} # we have the error in get-gitmodule
44+
$ModuleName = $RemoteModuleInfo.Name
45+
46+
# TODO: continue only after cleanup!
47+
48+
# Check version, and if higher install it
49+
$AllModules = @((Get-Module -Name $ModuleName -ListAvailable),(Get-InstalledModule -Name $ModuleName)) | Select Name, Version
50+
$LocalModuleInfo = $AllModules | Sort-Object Version -Descending | Select -First 1
51+
if (!$LocalModuleInfo) {
52+
Write-Error "$FunctionName cannot find local module '$ModuleName'"
53+
continue
54+
}
55+
if ($LocalModuleInfo.Version -ge $RemoteModuleInfo.Version) {
56+
Write-Verbose "$(Get-Date -f T) not updating module '$ModuleName', local version $($LocalModuleInfo.Version), remote version $($RemoteModuleInfo.Version)"
57+
} else {
58+
Install-ModuleInfo -ModuleInfo $RemoteModuleInfo -DestinationPath $DestinationPath -Force:$Force
59+
}
60+
61+
}
62+
}
63+
64+
END {
65+
Write-Verbose -Message "$(Get-Date -f G) $FunctionName completed"
66+
}
67+
68+
}

‎README.md

+12-6
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,6 @@ PS:\> (Install-GitModule 'https://github.com/iricigor/psaptgetupdate').Name | Im
5757

5858
The module Install Module From Git exposes two new commandlets. More info on module [here](/Docs/InstallModuleFromGit.md).
5959

60-
Module provides updatable help system, though it is working currently only on Windows PowerShell. Tracking issue is [here](https://github.com/iricigor/InstallModuleFromGit/issues/3).
61-
62-
```PowerShell
63-
Update-Help -Module InstallModuleFromGit -Force
64-
```
65-
6660
### Get-GitModule
6761

6862
Checks for module existence and returns its version. More info [here](/Docs/Get-GitModule.md).
@@ -71,6 +65,18 @@ Checks for module existence and returns its version. More info [here](/Docs/Get-
7165

7266
Installs PowerShell module to user's default install folder. More info [here](/Docs/Install-GitModule.md).
7367

68+
### Update-GitModule
69+
70+
Updates previously installed PowerShell module if Git repository contains newer version. More info [here](/Docs/Update-GitModule.md).
71+
72+
### Commands Help System
73+
74+
Module provides updatable help system, though it is working currently only on Windows PowerShell. Tracking issue is [here](https://github.com/iricigor/InstallModuleFromGit/issues/3).
75+
76+
```PowerShell
77+
Update-Help -Module InstallModuleFromGit -Force
78+
```
79+
7480
## Tests
7581

7682
:smirk: Module has testing against two platforms - Linux and Windows. Code is verified before and after merging to master branch. Tests results are available on the Tests tab ([example here](/img/TestResults-AzureDevops.png)).
+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#
2+
# This is a PowerShell Unit Test file.
3+
# You need a unit test framework such as Pester to run PowerShell Unit tests.
4+
# You can download Pester from http://go.microsoft.com/fwlink/?LinkID=534084
5+
#
6+
7+
$CommandName = 'Update-GitModule'
8+
9+
Describe "$CommandName basic testing" -Tag 'Functionality' {
10+
11+
12+
$moduleName = 'FIFA2018'
13+
$moduleURL = 'https://github.com/iricigor/' + $moduleName
14+
15+
$ExistingModule = Get-InstalledModule $moduleName -ea 0
16+
It 'Should uninstall module if installed' -Skip:($ExistingModule -eq $null) {
17+
{Uninstall-Module $moduleName} | Should -Not -Throw
18+
}
19+
20+
# its not so easy to remove PowerShell module
21+
$ExistingModule = Get-Module $moduleName -ListAvailable
22+
It 'Should delete module if still found' -Skip:($ExistingModule -eq $null) {
23+
{Split-Path ($ExistingModule.Path) -Parent | Remove-Item -Force -Recurse} | Should -Not -Throw
24+
}
25+
26+
It 'Should install module from PSGallery' {
27+
$OldProgressPreference = $ProgressPreference
28+
$ProgressPreference = 'SilentlyContinue'
29+
{Install-Module $moduleName -Repository PSGallery -Scope CurrentUser -Force} | Should -Not -Throw
30+
$ProgressPreference = $OldProgressPreference
31+
}
32+
33+
It 'Should update module to newer version' {
34+
Update-GitModule -ProjectUri $moduleURL -Force | Should -Not -Be $null
35+
}
36+
37+
}
38+
39+
40+
Describe "$CommandName error handling" -Tag 'Functionality' {
41+
42+
$moduleName = 'dbatools'
43+
$moduleURL = 'https://github.com/sqlcollaborative/' + $moduleName
44+
45+
It "Should not update non existing module" -Skip:((Get-Module $moduleName -ListAvailable) -ne $null) {
46+
{Update-GitModule -ProjectUri $moduleURL -ea Stop} | Should -Throw
47+
}
48+
49+
}

‎Tests/module/InstallModuleFromGit.Tests.ps1

+12-3
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,17 @@ Describe 'Proper Module Declaration' -Tag 'Documentation' {
4949

5050

5151
#
52-
# Module should import two functions
52+
# Module should import three functions
5353
#
5454

5555

5656
Describe 'Proper Functions Declaration' -Tag 'Other' {
5757

5858
It 'Checks for existence of functions' {
59-
@(Get-Command -Module $ModuleName -CommandType Function).Count | Should -Be 2 -Because 'We should have two functions defined'
59+
@(Get-Command -Module $ModuleName -CommandType Function).Count | Should -Be 3 -Because 'We should have two functions defined'
6060
Get-Command NonExistingCommand -ea 0 | Should -Be $Null
6161
Get-Command Get-GitModule -ea 0 | Should -Not -Be $Null
62+
Get-Command Update-GitModule -ea 0 | Should -Not -Be $Null
6263
Get-Command Install-GitModule -ea 0 | Should -Not -Be $Null
6364
}
6465
}
@@ -82,7 +83,15 @@ Describe 'Proper Documentation' -Tag 'Documentation' {
8283
$diff = git diff --ignore-space-change .\Docs .\en-US
8384
Pop-Location
8485
$diff | Should -Be $null
85-
}
86+
}
87+
88+
$Blank = '{{ Fill .+}}'
89+
foreach ($File in (Get-ChildItem .\Docs)) {
90+
It "Documentation for $($File.Name) should not have blanks" {
91+
Get-Content $File.FullName | Select-String -Pattern $Blank | Should -Be $null
92+
}
93+
}
94+
8695
}
8796

8897

‎cab/InstallModuleFromGit_d6a1577c-e3b5-48f2-a698-f08ab4865a58_HelpInfo.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@
77
<UICultureVersion>1.0.0.0</UICultureVersion>
88
</UICulture>
99
</SupportedUICultures>
10-
</HelpInfo>
10+
</HelpInfo>
Binary file not shown.
Binary file not shown.

‎tools/InvokeTests.ps1

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ function InstallModule ([string]$Name,[version]$Version){
2424
if ($env:TF_BUILD) {
2525
$PSVersionTable
2626
Get-ChildItem Env:\
27+
$Env:PSModulePath -split (';:'[[int]($IsLinux -or $IsMacOS)])
2728
Get-Module -ListAvailable | Format-Table -Property ModuleType, Name, Version
2829
}
2930

0 commit comments

Comments
 (0)
Please sign in to comment.