Skip to content

Instantly share code, notes, and snippets.

@amarruedo
Last active September 13, 2022 07:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amarruedo/0e989c0294f08c69b548a6c572d20fee to your computer and use it in GitHub Desktop.
Save amarruedo/0e989c0294f08c69b548a6c572d20fee to your computer and use it in GitHub Desktop.
Mirror NuGet server packages to Artifactory NuGet repository
# --- 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