1
+ # !/usr/bin/env pwsh
2
+
3
+ [cmdletbinding ()]
4
+ param ()
5
+
6
+ if (-not (Get-Module - ListAvailable GitHubActions)) {
7
+ Install-Module GitHubActions - Force
8
+ }
9
+
10
+ Import-Module GitHubActions
11
+
12
+ # # Pull in some inputs
13
+ $repositoryUrl = Get-ActionInput repositoryUrl - Required
14
+ $defaultBranch = Get-ActionInput defaultBranch
15
+ $rootDocsFolder = Get-ActionInput root
16
+ $convertRootReadmeToHomePage = Get-ActionInput convertRootReadmeToHomePage
17
+ $useHeaderForWikiName = Get-ActionInput useHeaderForWikiName
18
+
19
+ $wikiRepoName = ($repositoryUrl -split " /" )[-1 ] + " .wiki"
20
+ $wikiRepoUrl = " $repositoryUrl .wiki.git"
21
+
22
+ if (-not $defaultBranch ) {
23
+ $defaultBranch = git branch -- show-current
24
+ }
25
+
26
+ if (-not $rootDocsFolder )
27
+ {
28
+ $rootDocsFolder = " ."
29
+ $rootDocsFolderDirs = @ ()
30
+ }
31
+ else
32
+ {
33
+ $rootDocsFolderDirs = $rootDocsFolder -split " /"
34
+ }
35
+
36
+ $filenameToWikiNameMap = @ {}
37
+ $wikiNameToFileNameMap = @ {}
38
+
39
+ Function ProcessSourceDirectory ()
40
+ {
41
+ [cmdletbinding ()]
42
+ param ([string []]$directories = @ ())
43
+
44
+ foreach ($file in Get-ChildItem " *.md" )
45
+ {
46
+ ProcessSourceFile $file $directories
47
+ }
48
+
49
+ foreach ($dir in Get-ChildItem - Directory)
50
+ {
51
+ Push-Location $dir.Name
52
+
53
+ ProcessSourceDirectory ($directories + @ ($dir.Name ))
54
+
55
+ Pop-Location
56
+ }
57
+ }
58
+
59
+ Function ProcessSourceFile ()
60
+ {
61
+ [cmdletbinding ()]
62
+ param ($file , [string []]$directories )
63
+
64
+ Write-Verbose " Processing file $ ( $file.FullName ) "
65
+
66
+ $outputFileName = ($directories + $file.Name ) -join " __"
67
+
68
+ $content = Get-Content - Path $file.FullName
69
+ $content = UpdateFileLinks $file.Name $directories $content
70
+
71
+ $override = GetOutputFileNameFromFile $content
72
+
73
+ if ($convertRootReadmeToHomePage -and ($directories.Count -eq 0 ) -and ($file.Name -eq " readme.md" ))
74
+ {
75
+ $outputFileName = " Home.md"
76
+ }
77
+ elseif ($override )
78
+ {
79
+ Write-Verbose " Using overridden file name $ ( $override.FileName ) "
80
+
81
+ if ($wikiNameToFileNameMap [$override.FileName ])
82
+ {
83
+ throw " Overridden file name $ ( $override.FileName ) is already in use by $ ( $wikiNameToFileNameMap [$override.FileName ]) "
84
+ }
85
+ $wikiNameToFileNameMap [$override.FileName ] = $outputFileName
86
+
87
+ $filenameToWikiNameMap [$outputFileName ] = $override.FileName
88
+ $outputFileName = $override.FileName
89
+
90
+ $content = $override.NewContent
91
+ }
92
+
93
+ $outputPath = $wikiRepoPath + " /" + $outputFileName
94
+
95
+ $content | Set-Content - Path $outputPath
96
+ }
97
+
98
+ Function GetOutputFileNameFromFile ()
99
+ {
100
+ [cmdletbinding ()]
101
+ param ($content )
102
+
103
+ if ($useHeaderForWikiName )
104
+ {
105
+ $firstLine = $content | Select-Object - First 1
106
+ $headerMatch = [regex ]::match($firstLine , " ^#\s+(.*)$" )
107
+ if ($headerMatch.Success )
108
+ {
109
+ $filename = $headerMatch.Groups [1 ].Value
110
+ $filename = $filename -replace " " , " -"
111
+ $filename = $filename -replace " [^A-Za-z0-9\s.(){}_!?-]" , " "
112
+
113
+ return @ {
114
+ FileName = " $filename .md" ;
115
+ NewContent = $content [1 .. $content.Count ];
116
+ }
117
+ }
118
+ }
119
+ }
120
+
121
+ Function UpdateFileLinks ()
122
+ {
123
+ [cmdletbinding ()]
124
+ param ($filename , [string []]$directories , $content )
125
+
126
+ $evaluator = {
127
+ [cmdletbinding ()]
128
+ param ($match )
129
+
130
+ $text = $match.Groups [1 ].Value
131
+ $link = $match.Groups [2 ].Value
132
+
133
+ if ($link -like " http*" )
134
+ {
135
+ # Absolute link, no change
136
+ Write-Verbose " Link $link is already absolute, nothing to do"
137
+ return " [$text ]($link )"
138
+ }
139
+
140
+ $upDirs = 0
141
+ $path = @ ()
142
+
143
+ $link -split " /" | % {
144
+ if ($_ -eq " .." )
145
+ {
146
+ $upDirs += 1
147
+ }
148
+ else
149
+ {
150
+ $path += @ ($_ )
151
+ }
152
+ }
153
+
154
+ if (($upDirs -le $directories.Count ) -and ($link -like " *.md" ))
155
+ {
156
+ # Link to another doc which should now point to a wiki file
157
+
158
+ $relativeWikiPath = @ ($directories | Select-Object - First ($directories.Count - $upDirs )) + @ ($path )
159
+ $wikiFileName = ($relativeWikiPath -join " __" ) -replace " .md$" , " "
160
+
161
+ Write-Verbose " Link $link updated to $wikiFileName "
162
+ return " [$text ]($wikiFileName )"
163
+ }
164
+
165
+ # Outside the root directory or not a doc, convert to absolute Url
166
+ $extraUpDirs = $upDirs - $directories.Count
167
+
168
+ if ($extraUpDirs -gt $rootDocsFolderDirs.Count )
169
+ {
170
+ throw " Relative link $link in $filename does not exist"
171
+ }
172
+
173
+ $relativePathFromRoot = ($rootDocsFolderDirs | Select-Object - First ($rootDocsFolderDirs.Count - $extraUpDirs )) -join " /"
174
+ if ($relativePathFromRoot ) { $relativePathFromRoot += " /" }
175
+
176
+ $absoluteLink = $repositoryUrl + " /blob/$defaultBranch /" + $relativePathFromRoot + ($path -join " /" )
177
+
178
+ if ($link -like " *.md" )
179
+ {
180
+ Write-Verbose " Link $link is outside the docs root, updating to absolute link $absoluteLink "
181
+ }
182
+ else
183
+ {
184
+ Write-Verbose " Link $link is not a doc, updating to absolute link $absoluteLink "
185
+ }
186
+
187
+ return " [$text ]($absoluteLink )"
188
+ }
189
+
190
+ # TODO - handle nested brackets
191
+ # Matches `[text](link)`
192
+ $linkRegex = [regex ]" \[([^\]]+)\]\(([^\)]+)\)"
193
+
194
+ $content | % { $linkRegex.Replace ($_ , $evaluator ) }
195
+ }
196
+
197
+ Function ProcessWikiDirectory ()
198
+ {
199
+ [cmdletbinding ()]
200
+ param ([string []]$directories = @ ())
201
+
202
+ foreach ($file in Get-ChildItem " *.md" )
203
+ {
204
+ ProcessWikiFile $file $directories
205
+ }
206
+
207
+ foreach ($dir in Get-ChildItem - Directory)
208
+ {
209
+ Push-Location $dir.Name
210
+
211
+ ProcessWikiDirectory ($directories + @ ($dir.Name ))
212
+
213
+ Pop-Location
214
+ }
215
+ }
216
+
217
+ Function ProcessWikiFile ()
218
+ {
219
+ [cmdletbinding ()]
220
+ param ($file , [string []]$directories )
221
+
222
+ Write-Verbose " Processing file $ ( $file.Name ) "
223
+
224
+ $content = Get-Content $file
225
+ $filenameToWikiNameMap.Keys | % {
226
+ $originalLink = $_ -replace " .md$" , " "
227
+ $newLink = $filenameToWikiNameMap [$_ ] -replace " .md$" , " "
228
+
229
+ $content = $content -replace $originalLink , $newLink
230
+ }
231
+
232
+ Set-Content - Path $file.FullName - Value $content - Force
233
+ }
234
+
235
+ Push-Location ..
236
+ Write-Information " Cloning wiki repo..."
237
+ git clone $wikiRepoUrl
238
+ $wikiRepoPath = $pwd.Path + " /" + $wikiRepoName
239
+ cd $wikiRepoName
240
+ git rm - rf * | Out-Null
241
+ Pop-Location
242
+
243
+ Push-Location $rootDocsFolder
244
+ Write-Information " Processing source directory..."
245
+ ProcessSourceDirectory
246
+ Pop-Location
247
+
248
+ Push-Location ..\$wikiRepoName
249
+ Write-Information " Post-processing wiki files..."
250
+ ProcessWikiDirectory
251
+
252
+ Write-Information " Pushing wiki"
253
+ git add .
254
+ git commit - am " Sync Files"
255
+ git push
256
+ Pop-Location
0 commit comments