private static void AddPackage(string folder, string packageName, string version = null, bool restore = false) { var packagesFolder = Path.Combine(folder, "packages"); if (!Directory.Exists(packagesFolder)) { Directory.CreateDirectory(packagesFolder); } bool hasVersion = !string.IsNullOrWhiteSpace(version); string name = packageName + (hasVersion ? "." + version : ""); string localFile = Path.Combine(packagesFolder, name + ".nupkg"); if (File.Exists(localFile)) { File.Delete(localFile); } var msg = $"Installing {packageName} "; if (!ConsoleSpinner.DumbTerm) { if (msg.Length <= 29) { msg = msg.PadRight(29); } } Console.Write(msg); if (Directory.Exists(Path.Combine(packagesFolder, name))) { Warn("skipped (already exists)"); return; } try { string packageFolder = null; bool exists = false; bool success = false; var repos = GetRepos(); PackageRequestResult result = null; using (var spinner = new ConsoleSpinner()) { spinner.Start(); foreach (var repo in repos) { result = RequestPackage(repo, packageName, version, localFile, packagesFolder); if (result.Success) { exists = result.Exists; packageFolder = result.Folder; success = true; break; } } } if (!success) { if (result != null && result.Exception != null) { Error("failed."); throw result.Exception; } else { Error("not found."); } } else if (exists) { Warn("skipped (already exists)"); } else { Info("done."); if (!restore) { RemovePackage(folder, packageName); } Directory.CreateDirectory(packageFolder); ZipFile.ExtractToDirectory(localFile, packageFolder); File.Move(localFile, Path.Combine(packageFolder, Path.GetFileName(packageFolder) + ".nupkg")); PackageInfo info = null; if (!restore) { info = ReadPackageInfo(packageName, packageFolder); AddPackageToConfig(folder, info.Id, info.Version); } CleanPackageAfterDownload(packageFolder); if (info != null && !restore) { DownloadDependencies(folder, info); } } } catch (Exception e) { var exceptionChain = ""; var currException = e; while (currException != null) { exceptionChain += "- " + currException.Message + nl; currException = currException.InnerException; } Error("Error: " + nl + exceptionChain); #if DEBUG throw e; #endif } }
private static PackageRequestResult RequestPackage(string repoPath, string packageName, string version, string localFile, string packagesFolder) { var result = new PackageRequestResult(); bool hasVersion = !string.IsNullOrWhiteSpace(version); try { if (Directory.Exists(repoPath)) { string name = null; if (hasVersion) { name = packageName + "." + version; } else { var packages = Directory.GetFiles(repoPath, "*.nupkg", SearchOption.TopDirectoryOnly); var escapedName = packageName.Replace(".", @"\."); string pattern = "\\A" + escapedName + "\\.\\d+(\\.\\d+){2}\\z"; // Prerelease-aware pattern if (Program.EnablePrerelease) { pattern = "\\A" + escapedName + "\\.\\d+(\\.\\d+){2}(|-.*)\\z"; } version = null; InformationalVersion latestVersion = null; foreach (var p in packages) { var pName = Path.GetFileNameWithoutExtension(p); if (Regex.IsMatch(pName, pattern, RegexOptions.IgnoreCase)) { var pVersion = new InformationalVersion(pName.Substring(packageName.Length + 1)); if (latestVersion == null) { latestVersion = pVersion; } else if (pVersion > latestVersion) { latestVersion = pVersion; } } } if (latestVersion == null) { return(result); } BridgeVersion.ValidatePackageVersion(packageName, repoPath, latestVersion); name = packageName + "." + latestVersion; } name = name[0].ToString().ToUpper() + name.Substring(1); var packageFolder = Path.Combine(packagesFolder, name); result.Folder = packageFolder; if (Directory.Exists(packageFolder)) { result.Exists = true; result.Success = true; } else { var packageFile = Path.Combine(repoPath, name + ".nupkg"); if (File.Exists(packageFile)) { File.Copy(packageFile, localFile, true); result.Success = true; } else { result.Success = false; } } } else { var isFile = true; try { var uri = new Uri(repoPath); isFile = uri.IsFile; } catch (Exception) { } if (!isFile) { if (!repoPath.EndsWith("/")) { repoPath += "/"; } string uri = repoPath + packageName + (hasVersion ? "/" + version : ""); string name = null; if (hasVersion) { name = packageName + "." + version; } else { var webRequest = (HttpWebRequest)WebRequest.Create(uri + "?" + new Random().Next()); webRequest.AllowAutoRedirect = false; var webResponse = (HttpWebResponse)webRequest.GetResponse(); if (!String.IsNullOrEmpty(webResponse.Headers["Location"])) { var fileName = System.IO.Path.GetFileName(webResponse.Headers["Location"]); name = Path.GetFileNameWithoutExtension(fileName); } BridgeVersion.ValidatePackageVersion(packageName, repoPath, name.Substring(packageName.Length + 1)); webResponse.Dispose(); } name = name[0].ToString().ToUpper() + name.Substring(1); var packageFolder = Path.Combine(packagesFolder, name); result.Folder = packageFolder; if (Directory.Exists(packageFolder)) { result.Exists = true; result.Success = true; } else { WebClient client = new WebClient(); client.DownloadFile(uri, localFile); client.Dispose(); result.Success = true; } } } } catch (Exception e) { result.Success = false; result.Exception = new Exception("Package request failed.", e); } return(result); }