Last active
September 13, 2022 07:07
-
-
Save amarruedo/0e989c0294f08c69b548a6c572d20fee to your computer and use it in GitHub Desktop.
Mirror NuGet server packages to Artifactory NuGet repository
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# --- settings --- | |
$feedUrlBase = "<nuget_server_url>" | |
# the rest will be params when converting to funclet | |
$latest = $false | |
$overwrite = $false | |
$top = $null #use $top = $null to grab all | |
$destinationDirectory = join-path ([Environment]::GetFolderPath("MyDocuments")) "NuGetLocal" | |
# --- locals --- | |
$webClient = New-Object System.Net.WebClient | |
# ---- artifactory ---- | |
$nugetServer = "<artifactory_nuget_repo_url>" | |
$apiKey = "<arifactory_user>:<artifactory_api_key>" | |
# --- companies --- | |
$companies = @{"g.lerchundi" = "SALTO"; | |
"j.basurko" = "SALTO"; | |
"Salto" = "SALTO"; | |
"tfsbuild" = "SALTO"; | |
"Microsoft" = "Microsoft"; | |
"Microsoft,aspnet" = "Microsoft"; | |
"microsoft,dotnetframework" = "Microsoft"; | |
"protobuf-packages" = "Google"; | |
"Apache" = "Apache"; | |
"JiÅ™Ã" = "Apache"; | |
"Castle" = "Castle"; | |
"NDesk" = "NDesk"; | |
"James Newkirk,Brad Wilson" = "XUnit"} | |
# -- package exceptions --- | |
$blackList = @("Newtonsoft.Json") | |
# --- functions --- | |
# download entries on a page, recursively called for page continuations | |
function DownloadEntries { | |
param ([string]$feedUrl) | |
$feed = [xml]$webClient.DownloadString($feedUrl) | |
$entries = $feed.feed.entry | |
$progress = 0 | |
foreach ($entry in $entries) { | |
$url = $entry.content.src | |
$module = [string]$entry.title.'#text' | |
$fileName = $module + "." + $entry.properties.version + ".nupkg" | |
$company = GetCompanyFromOwner $entry.properties.Owners | |
$saveFileName = join-path $destinationDirectory $fileName | |
$pagepercent = ((++$progress)/$entries.Length*100) | |
if ((-not $overwrite) -and (Test-Path -path $saveFileName)) | |
{ | |
write-progress -activity "$fileName already downloaded" ` | |
-status "$pagepercent% of current page complete" ` | |
-percentcomplete $pagepercent | |
continue | |
} | |
write-progress -activity "Downloading $fileName " ` | |
-status "$pagepercent% of current page complete" ` | |
-percentcomplete $pagepercent | |
[int]$trials = 0 | |
do { | |
try { | |
$trials +=1 | |
$webClient.DownloadFile($url, $saveFileName) | |
break | |
} catch [System.Net.WebException] { | |
write-host "Problem downloading $url `tTrial $trials ` | |
`n`tException: " $_.Exception.Message | |
} | |
} | |
while ($trials -lt 3) | |
try{ | |
if($blackList –notcontains $module){ | |
$source = $nugetServer + "/" + $company + "/" + $module | |
Write-Host "Uploading to Artifactory: " $source | |
nuget push $saveFileName -Source $source -ApiKey $apiKey -Timeout 60 | Out-Null | |
} | |
}catch [System.Net.WebException] { | |
write-host "Problem uploading $source/$fileName | |
`n`tException: " $_.Exception.Message | |
} | |
} | |
$link = $feed.feed.link | where { $_.rel.startsWith("next") } | select href | |
if ($link -ne $null) { | |
# if using a paged url with a $skiptoken like | |
# http:// ... /Packages?$skiptoken='EnyimMemcached-log4net','2.7' | |
# remember that you need to escape the $ in powershell with ` | |
return $link.href | |
} | |
return $null | |
} | |
# the NuGet feed uses a fwlink which redirects | |
# using this to follow the redirect | |
function GetPackageUrl { | |
param ([string]$feedUrlBase) | |
$resp = [xml]$webClient.DownloadString($feedUrlBase) | |
return $resp.service.GetAttribute("xml:base") | |
} | |
# in order to satisfy Artifactory NuGet repo layout | |
# we need to figure out the [orgPath] or company name | |
# | |
# [orgPath]/[module]/[module].[baseRev](-[fileItegRev]).nupkg | |
# | |
# we use package owner to do that | |
function GetCompanyFromOwner { | |
param([string]$owner) | |
$o = $owner.Split(" ")[0] | |
if (!$companies.ContainsKey($o)) | |
{ | |
return "MISC" | |
} | |
else | |
{ | |
return $companies.Get_Item($o) | |
} | |
} | |
# --- do the actual work --- | |
# if dest dir doesn't exist, create it | |
if (!(Test-Path -path $destinationDirectory)) { | |
New-Item $destinationDirectory -type directory | |
} | |
# set up feed URL | |
$serviceBase = GetPackageUrl($feedUrlBase) | |
$feedUrl = $serviceBase + "Packages" | |
if($latest) { | |
$feedUrl = $feedUrl + "?`$filter=IsLatestVersion eq true" | |
if($top -ne $null) { | |
$feedUrl = $feedUrl + "&`$orderby=DownloadCount desc&`$top=$top" | |
} | |
} | |
[int]$pageNUmber = 1 | |
while($feedUrl -ne $null) { | |
Write-Host "Page" $pageNUmber "Link:" $feedUrl | |
$feedUrl = DownloadEntries $feedUrl | |
$pageNUmber += 1 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment