src/documentation/Update-ReadmeFromPlatyPSMarkdown.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
using module .\.\MKDocumentationInfo.psm1

function Update-ReadmeFromPlatyPSMarkdown {
    [CmdletBinding(PositionalBinding = $true, 
        DefaultParameterSetName = "ByPath")]
    Param
    (
        [Parameter(Mandatory = $false,
            Position = 0,
            ValueFromPipeline = $false, 
            ParameterSetName = "ByPath")]
        [string]$Path = '.',

        [Parameter(Mandatory = $true,
            Position = 1,
            ValueFromPipeline = $true, 
            ParameterSetName = "ByPipe")]
        [MKDocumentationInfo]$DocInfo,

        [Parameter(Mandatory = $false)]
        [string]$MarkdownFolder = 'docs',

        [Parameter(Mandatory = $false)]
        [string]$FileName = 'README.md'
    )
    
    DynamicParam {
        return GetModuleNameSet -Mandatory -Position 0
    }
    
    begin {
        $Name = $PSBoundParameters['Name']

        if (-not $DocInfo) {
            $DocInfo = [MKDocumentationInfo]::new(
                $Name,
                $Path,
                $MarkdownFolder
            )
        }
    }

    end {
        try {
            $MarkdownSnippetCollection = $DocInfo.GetMarkdownSnippetCollectionString()

            $ReadMePath = Join-Path -Path $DocInfo.ModuleFolder -ChildPath $FileName
            if ((Test-Path -Path $ReadMePath) -eq $false) {
                New-Item -Path $ReadMePath -ItemType File
            }

            $ReadMeContent = Get-Content -Path $ReadMePath -Raw

            if ($ReadMeContent) {
                $ModuleName = $DocInfo.ModuleName
                
                $MatchEvaluator = {
                    param($match)
                    $NewGitBranchName = $DocInfo.GitBranchName
                    # this $match.Value is a single link, $ModuleLinkMatches is regex with 2 groups, one being 'GitBranchName' which is the exisitng branchname
                    $ModuleLinkMatches = [regex]::Matches($match.Value, "(?<UrlSegmentPriorToGitBranchName>^.*blob)(?:\/|\\)(?<GitBranchName>.+?(?=\/|\\))")
                    $GitBranchName = $ModuleLinkMatches.Groups | Where-Object -Property Name -EQ 'GitBranchName' | Select-Object -ExpandProperty value
                    return $match.Value.Replace($GitBranchName, $NewGitBranchName)
                }
    
                [regex]$ExisitngRepositoryLinkPattern = "(?<=\()[^\)]+(?:$ModuleName)[^\(]+(?=\))"
                $ReadMeContent = $ExisitngRepositoryLinkPattern.Replace($ReadMeContent, $MatchEvaluator)

                # TODO: need to make this expression more specific so that it doesnt match a file from
                # another repository. Having the '####' prefix makes the possibility low.
                $ExistingSnippetPattern = "(?<link>#### \[.*\w+-\w+.*\]\(http.*\))(?:\s*)(?<body>[\w\W]+?)(?(?=####)(?=####)|(?=(?:##|\z)))"
                $FirstIndex = [regex]::Matches($ReadMeContent, $ExistingSnippetPattern, 'm') | Select-Object -First 1 -ExpandProperty Index
            }

            if ($FirstIndex) {
                $LastIndex = [regex]::Matches($ReadMeContent, $ExistingSnippetPattern, 'm') | Select-Object -Last 1 -ExpandProperty Index
                $LastLength = [regex]::Matches($ReadMeContent, $ExistingSnippetPattern, 'm') | Select-Object -Last 1 -ExpandProperty Length
                $ReadMeContent = $ReadMeContent.Remove($FirstIndex, (($LastIndex + $LastLength) - $FirstIndex))

                # TODO: may want to use StringBuilder here
                $MarkdownSnippetCollection = $MarkdownSnippetCollection.Trim()
            }
            else {
                $SubSectionTitle = @"
 
## API
"@

                # TODO: may want to use StringBuilder here
                $FirstIndex = 0
                $MarkdownSnippetCollection = $MarkdownSnippetCollection.Insert($FirstIndex, $SubSectionTitle)
                $MarkdownSnippetCollection += [Environment]::NewLine
            }
            
            # if: the file isn't new $FirstIndex will not be 0... else: $FirstIndex will be 0, just assign $MarkdownSnippetCollection
            if ($FirstIndex) {
                # TODO: yeah StringBuilder can be used here for sure or fix regex
                $ReadMeContent = $ReadMeContent.Insert($FirstIndex, [Environment]::NewLine)
                $ReadMeContent = $ReadMeContent.Insert($FirstIndex, [Environment]::NewLine)
                $ReadMeContent.Insert($FirstIndex, $MarkdownSnippetCollection) | Set-Content -Path $ReadMePath -NoNewline | Out-Null
            }
            else {
                Set-Content -Path $ReadMePath -Value $MarkdownSnippetCollection | Out-Null
            }
        }
        catch {
            Write-Error "Unable to update README file."
        }
    }
}