forked from brsh/lib.ps
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Create-LibPS.ps1
225 lines (195 loc) · 7.26 KB
/
Create-LibPS.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
<#
.SYNOPSIS
Clone and init the lib.ps
.DESCRIPTION
Tries to create and clone all the pieces of my lib.ps, putting everything in the proper place and sourcing as appropriate.
Of course, it's not perfect and has not been tested in every conceivable configuration. It will throw errors, but they should be non-fatal.
You will want to start a new instance of PowerShell and abandon the one you ran the script in :)
.EXAMPLE
PS C:\> Create-LibPS.ps1
Full on default mode
.EXAMPLE
PS C:\> Create-LibPS.ps1 -Folder c:\MyScripts
Save the library to C:\MyScripts rather than the default C:\Scripts
.EXAMPLE
PS C:\> Create-LibPS.ps1 -WhatIf
Don't do anything, but show me what you might have done...
#>
[CmdletBinding(SupportsShouldProcess)]
param (
[Parameter(Mandatory = $false)]
[string] $Folder = "C:\Scripts"
)
#For Writing/Troubleshooting purposes (and because I forget to set it at runtime)
#$VerbosePreference = "Continue"
#$VerbosePreference = "SilentlyContinue"
Function Read-Profiles {
#Reload all profiles - helpful when editing/testing profiles
Set-Variable -name isDotSourced -value $False -Scope 0
$isDotSourced = $MyInvocation.InvocationName -eq '.' -or $MyInvocation.Line -eq ''
if (!($isDotSourced)) {
write-host "You must dot source this function" -fore Red; write-host "`t. Load-Profiles`n`t. re-Profs"
-ForegroundColor "Yellow"; return ""
}
@(
$Profile.AllUsersAllHosts,
$Profile.AllUsersCurrentHost,
$Profile.CurrentUserAllHosts,
$Profile.CurrentUserCurrentHost
) | ForEach-Object {
if (Test-Path $_) {
Write-Host "Re-loading $_"
. $_
}
}
}
Function Remove-InvalidFileNameChars {
param(
[Parameter(Mandatory = $true, Position = 0)]
[String] $Text
)
#Let's remove invalid filesystem characters and ones we just don't like in filenames
$invalidChars = ([IO.Path]::GetInvalidFileNameChars() + "," + ";") -join ''
$invalidChars = $invalidChars.Replace("\", "")
$invalidChars = $invalidChars.Replace(":", "")
$invalidChars = $invalidChars.Replace(" ", "")
$re = "[{0}]" -f [RegEx]::Escape($invalidChars)
$Text = $Text -replace $re
return $Text
}
$Folder = Remove-InvalidFileNameChars $Folder
try {
[System.Management.Automation.PathInfo] $FolderInfo = Resolve-Path $Folder -ErrorAction Stop
[String] $HomeFolder = $FolderInfo.ProviderPath
} catch { $HomeFolder = $Folder }
if (-not $(Test-Path $HomeFolder -ErrorAction SilentlyContinue)) {
$Title = "The Folder, $HomeFolder, does not exist. Create it?"
$Info = "Would you like to continue?"
$Options = [System.Management.Automation.Host.ChoiceDescription[]] @("&Yes", "&No")
[int] $DefaultChoice = 0
$Response = $host.UI.PromptForChoice($Title , $Info, $Options, $DefaultChoice)
switch ($Response) {
0 { try { $HomeFolder = (new-item $HomeFolder -ItemType "Directory" -ErrorAction Stop).FullName } catch { "Couldn't create path $HomeFolder"; "$_"; exit }; break }
1 { Write-Warning "Terminating script"; exit; break }
}
}
Try {
if ($pscmdlet.ShouldProcess($HomeFolder, "Set-Location")) {
Set-Location $HomeFolder -ErrorAction Stop
}
} catch {
Write-Warning "Couldn't change directory to the new location $HomeFolder. Terminating script."
exit
}
"Testing if git is in the path"
$git = (get-command git.exe -ErrorAction SilentlyContinue).Source
if (-not ($git)) {
"Can't find git in path; trying GitHub's weird location..."
$git = (get-command (Resolve-Path "C:\Users\*\AppData\Local\GitHub\PortableGit_*\cmd\git.exe" | Select-Object -First 1).Path -ErrorAction SilentlyContinue).Source
if (-not ($git)) {
Write-Warning "Can't find git; terminating script"
exit
}
}
$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.FileName = $git
[string] $output = ""
if ($pscmdlet.ShouldProcess("LibPS", "Cloning Repository")) {
if (Test-Path $HomeFolder\Lib.PS -ErrorAction SilentlyContinue) {
$Title = "Lib.PS is already installed under $HomeFolder. This will overwrite and reset it!"
$Info = "Would you like to continue?"
$Options = [System.Management.Automation.Host.ChoiceDescription[]] @("&Yes", "&No")
[int] $DefaultChoice = 1
$Response = $host.UI.PromptForChoice($Title , $Info, $Options, $DefaultChoice)
switch ($Response) {
0 {
try {
set-location $HomeFolder\lib.ps
[Environment]::CurrentDirectory = (Get-Location -PSProvider FileSystem).ProviderPath
"Starting git fetch..."
$pinfo.Arguments = "fetch --all"
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$p.WaitForExit()
$output = ""
$output = $p.StandardError.ReadToEnd()
if ($output -ne "") { throw "Error running 'git fetch --all'"}
"Starting git reset..."
$pinfo.Arguments = "reset --hard origin/master"
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$p.WaitForExit()
$output = ""
$output = $p.StandardError.ReadToEnd()
if ($output -ne "") { throw "Error running 'git reset --hard origin/master'"}
"Starting git pull..."
$pinfo.Arguments = "pull origin master"
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$p.WaitForExit()
$output = ""
$output = $p.StandardError.ReadToEnd()
#if ($output -ne "") { throw "Error running 'git pull origin master'"}
#(fricken 'up-to-date' repo 'error')
} catch {
Write-Warning "Couldn't update/reset Lib.PS. Terminating script"
"Git error was: $($output)"
$_.Exception.Message
exit
} break
}
1 { "Terminating script"; set-location $HomeFolder; exit; break }
}
} else {
"Cloning Main Lib.PS"
$retval = Start-Process $git -ArgumentList "clone https://github.com/brsh/lib.ps" -Wait -NoNewWindow
}
}
if ($pscmdlet.ShouldProcess($PROFILE, "Adjusting default profile")) {
try {
"Updating your personal profile: $profile"
$loadtext = @"
if (test-path $HomeFolder\lib.ps\Profile\profile.ps1) {
. $HomeFolder\lib.ps\Profile\profile.ps1
}
"@
[bool] $DoUpdateProfile = $true
$profile | Get-Member *Host* | ForEach-Object { $_.name } |
ForEach-Object {
if (test-path ($profile).$_) {
if (Get-Content ($profile).$_ | Where-Object { $_.Contains("lib.ps") }) {
Write-Warning "Lib.ps exists in ($profile).$_ - Skipping."
"You might need to adjust the profile manually by adjusting with the following:"
$loadtext
$DoUpdateProfile = $false
}
}
}
if ($DoUpdateProfile) {
if (-not (test-path $profile)) { $null = New-item -type file -force $profile }
$loadtext | Out-File -Append -FilePath $profile -Force
}
. Read-Profiles
} Catch {
Write-Warning "Couldn't update $profile"
$_
"You will need to adjust the profile manually by adding the following:"
$loadtext
}
Set-Location $HomeFolder
}
if ($pscmdlet.ShouldProcess("Standard Modules/Scripts", "Cloning Sub-Repositories")) {
if (test-path ".\lib.ps\Scripts\Reset-Clones.ps1") {
if (-not (test-path $HomeFolder\lib.ps\Clones)) {mkdir $HomeFolder\lib.ps\Clones }
if (-not (test-path $HomeFolder\lib.ps\Modules)) { mkdir $HomeFolder\lib.ps\Modules }
.\lib.ps\Scripts\Reset-Clones.ps1 -Folder $HomeFolder\lib.ps
}
Set-Location $HomeFolder
}
if ($DoUpdateProfile) { . Read-Profiles }