protected override void BeginProcessing() { _cancellationTokenSource = new CancellationTokenSource(); _findHelper = new FindHelper( cancellationToken: _cancellationTokenSource.Token, cmdletPassedIn: this); // Create a repository story (the PSResourceRepository.xml file) if it does not already exist // This is to create a better experience for those who have just installed v3 and want to get up and running quickly RepositorySettings.CheckRepositoryStore(); }
// This method calls iterates through repositories (by priority order) to search for the pkgs to install private List <PSResourceInfo> ProcessRepositories( string[] repository, bool trustRepository, PSCredential credential, bool skipDependencyCheck) { var listOfRepositories = RepositorySettings.Read(repository, out string[] _); var yesToAll = false; var noToAll = false; var findHelper = new FindHelper(_cancellationToken, _cmdletPassedIn); List <PSResourceInfo> allPkgsInstalled = new List <PSResourceInfo>(); foreach (var repo in listOfRepositories) { // If no more packages to install, then return if (!_pkgNamesToInstall.Any()) { return(allPkgsInstalled); } string repoName = repo.Name; _cmdletPassedIn.WriteVerbose(string.Format("Attempting to search for packages in '{0}'", repoName)); // Source is only trusted if it's set at the repository level to be trusted, -TrustRepository flag is true, -Force flag is true // OR the user issues trust interactively via console. var sourceTrusted = true; if (repo.Trusted == false && !trustRepository && !_force) { _cmdletPassedIn.WriteVerbose("Checking if untrusted repository should be used"); if (!(yesToAll || noToAll)) { // Prompt for installation of package from untrusted repository var message = string.Format(CultureInfo.InvariantCulture, MsgInstallUntrustedPackage, repoName); sourceTrusted = _cmdletPassedIn.ShouldContinue(message, MsgRepositoryNotTrusted, true, ref yesToAll, ref noToAll); } } if (!sourceTrusted && !yesToAll) { continue; } _cmdletPassedIn.WriteVerbose("Untrusted repository accepted as trusted source."); // If it can't find the pkg in one repository, it'll look for it in the next repo in the list var isLocalRepo = repo.Url.AbsoluteUri.StartsWith(Uri.UriSchemeFile + Uri.SchemeDelimiter, StringComparison.OrdinalIgnoreCase); // Finds parent packages and dependencies IEnumerable <PSResourceInfo> pkgsFromRepoToInstall = findHelper.FindByResourceName( name: _pkgNamesToInstall.ToArray(), type: ResourceType.None, version: _versionRange != null ? _versionRange.OriginalString : null, prerelease: _prerelease, tag: null, repository: new string[] { repoName }, credential: credential, includeDependencies: !skipDependencyCheck); if (!pkgsFromRepoToInstall.Any()) { _cmdletPassedIn.WriteVerbose(string.Format("None of the specified resources were found in the '{0}' repository.", repoName)); // Check in the next repository continue; } // Select the first package from each name group, which is guaranteed to be the latest version. // We should only have one version returned for each package name // e.g.: // PackageA (version 1.0) // PackageB (version 2.0) // PackageC (version 1.0) pkgsFromRepoToInstall = pkgsFromRepoToInstall.GroupBy( m => new { m.Name }).Select( group => group.First()).ToList(); // Check to see if the pkgs (including dependencies) are already installed (ie the pkg is installed and the version satisfies the version range provided via param) if (!_reinstall) { pkgsFromRepoToInstall = FilterByInstalledPkgs(pkgsFromRepoToInstall); } if (!pkgsFromRepoToInstall.Any()) { continue; } List <PSResourceInfo> pkgsInstalled = InstallPackage( pkgsFromRepoToInstall, repo.Url.AbsoluteUri, credential, isLocalRepo); foreach (PSResourceInfo pkg in pkgsInstalled) { _pkgNamesToInstall.RemoveAll(x => x.Equals(pkg.Name, StringComparison.InvariantCultureIgnoreCase)); } allPkgsInstalled.AddRange(pkgsInstalled); } // At this only package names left were those which could not be found in registered repositories foreach (string pkgName in _pkgNamesToInstall) { var message = String.Format("Package '{0}' with requested version range {1} could not be installed as it was not found in any registered repositories", pkgName, _versionRange.ToString()); var ex = new ArgumentException(message); var ResourceNotFoundError = new ErrorRecord(ex, "ResourceNotFoundError", ErrorCategory.ObjectNotFound, null); _cmdletPassedIn.WriteError(ResourceNotFoundError); } return(allPkgsInstalled); }
protected override void ProcessRecord() { _path = string.IsNullOrEmpty(_path) ? _literalPath : _path; // Get the .psd1 file or .ps1 file // Returns the name of the file or the name of the directory, depending on path var pkgFileOrDir = new DirectoryInfo(_path); string moduleManifestOrScriptPath; if (isScript) { moduleManifestOrScriptPath = pkgFileOrDir.FullName; pkgName = pkgFileOrDir.Name.Remove(pkgFileOrDir.Name.Length - 4); } else { moduleManifestOrScriptPath = System.IO.Path.Combine(_path, pkgFileOrDir.Name + ".psd1"); // Validate that there's a module manifest if (!File.Exists(moduleManifestOrScriptPath)) { var message = String.Format("No file with a .psd1 extension was found in {0}. Please specify a path to a valid modulemanifest.", moduleManifestOrScriptPath); var ex = new ArgumentException(message); var moduleManifestNotFound = new ErrorRecord(ex, "moduleManifestNotFound", ErrorCategory.ObjectNotFound, null); this.ThrowTerminatingError(moduleManifestNotFound); } pkgName = pkgFileOrDir.Name; } FileInfo moduleFileInfo; moduleFileInfo = new FileInfo(moduleManifestOrScriptPath); // if there's no specified destination path to publish the nupkg, we'll just create a temp folder and delete it later string outputDir = !string.IsNullOrEmpty(_destinationPath) ? _destinationPath : System.IO.Path.Combine(System.IO.Path.GetTempPath(), Guid.NewGuid().ToString()); if (!Directory.Exists(outputDir)) { Directory.CreateDirectory(outputDir); } // if user does not specify that they want to use a nuspec they've created, we'll create a nuspec var dependencies = new Hashtable(); if (string.IsNullOrEmpty(_nuspec)) { _nuspec = createNuspec(outputDir, moduleFileInfo); } else { // Read the nuspec passed in to pull out the dependency information XDocument doc = XDocument.Load(_nuspec); // ex: <version>2.2.1</version> var versionNode = doc.Descendants("version"); NuGetVersion.TryParse(versionNode.FirstOrDefault().Value, out NuGetVersion version); if (version == null) { var message = "Version is not specified in the .nuspec provided. Please provide a valid version in the .nuspec."; var ex = new ArgumentException(message); var versionNotFound = new ErrorRecord(ex, "versionNotFound", ErrorCategory.NotSpecified, null); this.ThrowTerminatingError(versionNotFound); } // ex: <dependency id="Carbon" version="2.9.2" /> var dependencyNode = doc.Descendants("dependency"); foreach (var dep in dependencyNode) { dependencies.Add(dep.Attribute("id"), dep.Attribute("version")); } } // find repository var r = new RespositorySettings(); var repositoryUrl = r.Read(new[] { _repository }); if (!repositoryUrl.Any()) { var message = String.Format("The resource repository '{0}' is not a registered. Please run 'Register-PSResourceRepository' in order to publish to this repository.", _repository); var ex = new ArgumentException(message); var repositoryNotFound = new ErrorRecord(ex, "repositoryNotFound", ErrorCategory.ObjectNotFound, null); this.ThrowTerminatingError(repositoryNotFound); } if (!_skipDependenciesCheck) { // Check to see that all dependencies are in the repository var findHelper = new FindHelper(); foreach (var dependency in dependencies.Keys) { // Need to make individual calls since we're look for exact version numbers or ranges. var depName = new[] { (string)dependency }; var depVersion = (string)dependencies[dependency]; var type = new[] { "module", "script" }; var repository = new[] { _repository }; // Search for and return the dependency if it's in the repository. var dependencyFound = findHelper.beginFindHelper(depName, type, depVersion, true, null, null, repository, _credential, false, false); if (!dependencyFound.Any()) { var message = String.Format("Dependency {0} was not found in repository {1}. Make sure the dependency is published to the repository before publishing this module.", depName, _repository); var ex = new ArgumentException(message); // System.ArgumentException vs PSArgumentException var dependencyNotFound = new ErrorRecord(ex, "DependencyNotFound", ErrorCategory.ObjectNotFound, null); this.ThrowTerminatingError(dependencyNotFound); } } } if (isScript) { File.Copy(_path, System.IO.Path.Combine(outputDir, pkgName + ".ps1"), true); } else { // Create subdirectory structure in temp folder foreach (string dir in System.IO.Directory.GetDirectories(_path, "*", System.IO.SearchOption.AllDirectories)) { var dirName = dir.Substring(_path.Length).Trim(PathSeparators); System.IO.Directory.CreateDirectory(System.IO.Path.Combine(outputDir, dirName)); } // Copy files over to temp folder foreach (string fileNamePath in System.IO.Directory.GetFiles(_path, "*", System.IO.SearchOption.AllDirectories)) { var fileName = fileNamePath.Substring(_path.Length).Trim(PathSeparators); System.IO.File.Copy(fileNamePath, System.IO.Path.Combine(outputDir, fileName)); } } var outputDirectory = System.IO.Path.Combine(outputDir, "nupkg"); // Pack the module or script into a nupkg given a nuspec. var builder = new PackageBuilder(); var runner = new PackCommandRunner( new PackArgs { CurrentDirectory = outputDir, OutputDirectory = outputDirectory, Path = _nuspec, Exclude = _exclude, Symbols = false, Logger = NullLogger.Instance }, MSBuildProjectFactory.ProjectCreator, builder); runner.BuildPackage(); // Push the nupkg to the appropriate repository // Pkg version is parsed from .ps1 file or .psd1 file var fullNupkgPath = System.IO.Path.Combine(outputDirectory, pkgName + "." + pkgVersion.ToNormalizedString() + ".nupkg"); var repoURL = repositoryUrl.First().Properties["Url"].Value.ToString(); var publishLocation = repoURL.EndsWith("/v2", StringComparison.OrdinalIgnoreCase) ? repoURL + "/package" : repoURL; var settings = NuGet.Configuration.Settings.LoadDefaultSettings(null, null, null); NuGet.Common.ILogger log = new NuGetLogger(); PushRunner.Run( Settings.LoadDefaultSettings(root: null, configFileName: null, machineWideSettings: null), new PackageSourceProvider(settings), fullNupkgPath, publishLocation, _APIKey, // api key null, // symbols source null, // symbols api key 0, // timeout false, // disable buffering false, // no symbols // Skip duplicate: if a package and version already exists, skip it and continue with the next package in the push, if any. false, // no skip duplicate false, // enable server endpoint log).GetAwaiter().GetResult(); }
private void ProcessResourceNameParameterSet() { if (!MyInvocation.BoundParameters.ContainsKey(nameof(Name))) { // TODO: Add support for Tag and Type parameters without Name parameter being specified. if (MyInvocation.BoundParameters.ContainsKey(nameof(Type)) || MyInvocation.BoundParameters.ContainsKey(nameof(Tag))) { ThrowTerminatingError( new ErrorRecord( new PSNotImplementedException("Search by Tag or Type parameter is not yet implemented."), "TagTypeSearchNotYetImplemented", ErrorCategory.NotImplemented, this)); } ThrowTerminatingError( new ErrorRecord( new PSInvalidOperationException("Name parameter must be provided."), "NameParameterNotProvided", ErrorCategory.InvalidOperation, this)); } Name = Utils.FilterOutWildcardNames(Name, out string[] errorMsgs); foreach (string error in errorMsgs) { WriteError(new ErrorRecord( new PSInvalidOperationException(error), "ErrorFilteringNamesForUnsupportedWildcards", ErrorCategory.InvalidArgument, this)); } if (Name.Length == 0) { return; } FindHelper findHelper = new FindHelper(_cancellationToken, this); List <PSResourceInfo> foundPackages = new List <PSResourceInfo>(); foreach (PSResourceInfo package in findHelper.FindByResourceName( Name, Type, Version, Prerelease, Tag, Repository, Credential, IncludeDependencies)) { foundPackages.Add(package); } foreach (var uniquePackageVersion in foundPackages.GroupBy( m => new { m.Name, m.Version }).Select( group => group.First()).ToList()) { WriteObject(uniquePackageVersion); } }
// This method calls iterates through repositories (by priority order) to search for the pkgs to install public void ProcessRepositories(string[] packageNames, string[] repository, bool trustRepository, PSCredential credential) { var listOfRepositories = RepositorySettings.Read(repository, out string[] _); List <string> packagesToInstall = packageNames.ToList(); var yesToAll = false; var noToAll = false; var repositoryIsNotTrusted = "Untrusted repository"; var queryInstallUntrustedPackage = "You are installing the modules from an untrusted repository. If you trust this repository, change its Trusted value by running the Set-PSResourceRepository cmdlet. Are you sure you want to install the PSresource from '{0}' ?"; foreach (var repo in listOfRepositories) { // If no more packages to install, then return if (!packagesToInstall.Any()) { return; } var sourceTrusted = false; string repoName = repo.Name; _cmdletPassedIn.WriteDebug(string.Format("Attempting to search for packages in '{0}'", repoName)); // Source is only trusted if it's set at the repository level to be trusted, -TrustRepository flag is true, -Force flag is true // OR the user issues trust interactively via console. if (repo.Trusted == false && !trustRepository && !_force) { _cmdletPassedIn.WriteDebug("Checking if untrusted repository should be used"); if (!(yesToAll || noToAll)) { // Prompt for installation of package from untrusted repository var message = string.Format(CultureInfo.InvariantCulture, queryInstallUntrustedPackage, repoName); sourceTrusted = _cmdletPassedIn.ShouldContinue(message, repositoryIsNotTrusted, true, ref yesToAll, ref noToAll); } } else { sourceTrusted = true; } if (sourceTrusted || yesToAll) { _cmdletPassedIn.WriteDebug("Untrusted repository accepted as trusted source."); // If it can't find the pkg in one repository, it'll look for it in the next repo in the list var isLocalRepo = repo.Url.AbsoluteUri.StartsWith(Uri.UriSchemeFile + Uri.SchemeDelimiter, StringComparison.OrdinalIgnoreCase); var findHelper = new FindHelper(_cancellationToken, _cmdletPassedIn); // Finds parent packages and dependencies IEnumerable <PSResourceInfo> pkgsFromRepoToInstall = findHelper.FindByResourceName( name: packageNames, type: ResourceType.None, version: _versionRange != null ? _versionRange.OriginalString : null, prerelease: _prerelease, tag: null, repository: new string[] { repoName }, credential: credential, includeDependencies: true); foreach (PSResourceInfo a in pkgsFromRepoToInstall) { var test = a; _cmdletPassedIn.WriteVerbose(a.Version.ToString()); } // Select the first package from each name group, which is guaranteed to be the latest version. // We should only have one version returned for each package name // e.g.: // PackageA (version 1.0) // PackageB (version 2.0) // PackageC (version 1.0) pkgsFromRepoToInstall = pkgsFromRepoToInstall.GroupBy( m => new { m.Name }).Select( group => group.First()).ToList(); if (!pkgsFromRepoToInstall.Any()) { _cmdletPassedIn.WriteVerbose(string.Format("None of the specified resources were found in the '{0}' repository.", repoName)); // Check in the next repository continue; } // Check to see if the pkgs (including dependencies) are already installed (ie the pkg is installed and the version satisfies the version range provided via param) if (!_reinstall) { // Removes all of the names that are already installed from the list of names to search for pkgsFromRepoToInstall = FilterByInstalledPkgs(pkgsFromRepoToInstall); } if (!pkgsFromRepoToInstall.Any()) { continue; } List <string> pkgsInstalled = InstallPackage(pkgsFromRepoToInstall, repoName, repo.Url.AbsoluteUri, credential, isLocalRepo); foreach (string name in pkgsInstalled) { packagesToInstall.Remove(name); } } } }