-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCollect-OrgDocsSparse.ps1
More file actions
127 lines (109 loc) · 4.01 KB
/
Copy pathCollect-OrgDocsSparse.ps1
File metadata and controls
127 lines (109 loc) · 4.01 KB
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
#Requires -Version 7.0
<#
.SYNOPSIS
Sparse-checkouts docs/ from every public org repository into a corpus folder.
.DESCRIPTION
Produces {OutDir}/{repo}/docs/**/*.md for novolis-docs site. Uses git
partial clone + sparse-checkout so only the docs tree is materialized.
#>
param(
[string] $Org = 'Novolis-Platform',
[string] $OutDir = '',
[string] $Token = '',
[int] $Throttle = 6
)
$ErrorActionPreference = 'Stop'
$scriptDir = $PSScriptRoot
$repoRoot = (Resolve-Path (Join-Path $scriptDir '..')).Path
if ([string]::IsNullOrWhiteSpace($OutDir)) {
$OutDir = Join-Path $repoRoot 'corpus'
}
$outPath = [System.IO.Path]::GetFullPath($OutDir)
if (-not $outPath.StartsWith($repoRoot, [System.StringComparison]::OrdinalIgnoreCase)) {
throw "OutDir must stay inside $repoRoot (got $outPath)"
}
if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
throw 'git is required for sparse checkout'
}
if (-not (Get-Command gh -ErrorAction SilentlyContinue)) {
throw 'gh is required to list organization repositories'
}
if ([string]::IsNullOrWhiteSpace($Token)) {
$Token = $env:GH_TOKEN
if ([string]::IsNullOrWhiteSpace($Token)) { $Token = $env:GITHUB_TOKEN }
}
Write-Host "Listing public repositories for $Org..."
$repos = @(gh repo list $Org --visibility public --no-archived --limit 200 --json name,defaultBranchRef | ConvertFrom-Json | Sort-Object name)
if ($repos.Count -eq 0) {
throw "No public repositories found for $Org"
}
if (Test-Path $outPath) {
Remove-Item -LiteralPath $outPath -Recurse -Force
}
New-Item -ItemType Directory -Path $outPath | Out-Null
$work = [System.Collections.Concurrent.ConcurrentBag[string]]::new()
$errors = [System.Collections.Concurrent.ConcurrentBag[string]]::new()
$repos | ForEach-Object -ThrottleLimit $Throttle -Parallel {
$repo = $_
$name = [string]$repo.name
$branch = if ($repo.defaultBranchRef -and $repo.defaultBranchRef.name) { [string]$repo.defaultBranchRef.name } else { 'main' }
$dest = Join-Path $using:outPath $name
$org = $using:Org
$token = $using:Token
$workBag = $using:work
$errorBag = $using:errors
$url = if ([string]::IsNullOrWhiteSpace($token)) {
"https://github.com/$org/$name.git"
}
else {
"https://x-access-token:${token}@github.com/$org/$name.git"
}
try {
& git clone --filter=blob:none --sparse --depth 1 --branch $branch --quiet $url $dest 2>$null
if ($LASTEXITCODE -ne 0) {
throw "git clone failed for $name"
}
Push-Location $dest
try {
& git sparse-checkout set docs 2>$null
if ($LASTEXITCODE -ne 0) {
throw "sparse-checkout set docs failed for $name"
}
}
finally {
Pop-Location
}
$docsPath = Join-Path $dest 'docs'
if (-not (Test-Path $docsPath -PathType Container)) {
Remove-Item -LiteralPath $dest -Recurse -Force -ErrorAction SilentlyContinue
return
}
$mdCount = @(Get-ChildItem -Path $docsPath -Recurse -Filter '*.md' -File -ErrorAction SilentlyContinue).Count
if ($mdCount -eq 0) {
Remove-Item -LiteralPath $dest -Recurse -Force -ErrorAction SilentlyContinue
return
}
Remove-Item -LiteralPath (Join-Path $dest '.git') -Recurse -Force -ErrorAction SilentlyContinue
[void]$workBag.Add("$name ($mdCount md)")
}
catch {
[void]$errorBag.Add("${name}: $($_.Exception.Message)")
if (Test-Path $dest) {
Remove-Item -LiteralPath $dest -Recurse -Force -ErrorAction SilentlyContinue
}
}
}
Write-Host "Sparse corpus ready at $outPath"
Write-Host " repos_with_docs=$($work.Count)"
foreach ($line in ($work | Sort-Object)) {
Write-Host " + $line"
}
if ($errors.Count -gt 0) {
Write-Warning "Skipped/failed $($errors.Count) repositories:"
foreach ($line in ($errors | Sort-Object)) {
Write-Warning " - $line"
}
}
if ($work.Count -eq 0) {
throw 'No repository docs/ trees were collected'
}