Example #1
0
        /// <summary>
        /// Searches package sources given name and version information
        ///
        /// Package information must be returned using <c>request.YieldPackage(...)</c> function.
        /// </summary>
        /// <param name="name">a name or partial name of the package(s) requested</param>
        /// <param name="requiredVersion">A specific version of the package. Null or empty if the user did not specify</param>
        /// <param name="minimumVersion">A minimum version of the package. Null or empty if the user did not specify</param>
        /// <param name="maximumVersion">A maximum version of the package. Null or empty if the user did not specify</param>
        /// <param name="id">if this is greater than zero (and the number should have been generated using <c>StartFind(...)</c>, the core is calling this multiple times to do a batch search request. The operation can be delayed until <c>CompleteFind(...)</c> is called</param>
        /// <param name="request">An object passed in from the PackageManagement that contains functions that can be used to interact with its Provider</param> 
        public void FindPackage(string name, string requiredVersion, string minimumVersion, string maximumVersion, int id, NuGetRequest request)
        {
            if (request == null){
                throw new ArgumentNullException("request");
            }

            // true if we want to include the max and min version
            bool minInclusive = true;
            bool maxInclusive = true;

            // If finding by canonical id, then the version follows dependency version requirement
            if (request.GetOptionValue("FindByCanonicalId").IsTrue())
            {
                // Use the dependency version if no min and max is supplied
                if (String.IsNullOrWhiteSpace(maximumVersion) && String.IsNullOrWhiteSpace(minimumVersion))
                {
                    DependencyVersion depVers = DependencyVersion.ParseDependencyVersion(requiredVersion);
                    maximumVersion = depVers.MaxVersion.ToStringSafe();
                    minimumVersion = depVers.MinVersion.ToStringSafe();
                    minInclusive = depVers.IsMinInclusive;
                    maxInclusive = depVers.IsMaxInclusive;

                    // set required version if we have both min max as the same value.
                    if (depVers.MaxVersion != null && depVers.MinVersion != null
                        && depVers.MaxVersion == depVers.MinVersion && minInclusive && maxInclusive)
                    {
                        requiredVersion = maximumVersion;
                    }
                    else
                    {
                        requiredVersion = null;
                    }
                }                
            }

            request.Debug(Resources.Messages.DebugInfoCallMethod, PackageProviderName, string.Format(CultureInfo.InvariantCulture, "FindPackage' - name='{0}', requiredVersion='{1}',minimumVersion='{2}', maximumVersion='{3}'", name, requiredVersion, minimumVersion, maximumVersion));

            NormalizeVersion(request, ref requiredVersion, ref minimumVersion, ref maximumVersion);

            try {

            
            // If there are any packages, yield and return
            if (request.YieldPackages(request.GetPackageById(name, request, requiredVersion, minimumVersion, maximumVersion, minInclusive, maxInclusive), name))
            {
                return;
            }

            // Check if the name contains wildcards. If not, return. This matches the behavior as "Get-module xje" 
            if (!String.IsNullOrWhiteSpace(name) && !WildcardPattern.ContainsWildcardCharacters(name))
            {              
                return;
            }

            // In the case of the package name is null or contains wildcards, error out if a user puts version info
            if (!String.IsNullOrWhiteSpace(requiredVersion) || !String.IsNullOrWhiteSpace(minimumVersion) || !String.IsNullOrWhiteSpace(maximumVersion))
            {
                request.Warning( Constants.Messages.MissingRequiredParameter, "name");
                return;
            }
            
            
       
            // Have we been cancelled?
            if (request.IsCanceled) {
                request.Debug(Resources.Messages.RequestCanceled, PackageProviderName, "FindPackage");

                return;
            }

            // A user does not provide the package full Name at all Or used wildcard in the name. Let's try searching the entire repository for matches.
            request.YieldPackages(request.SearchForPackages(name), name);
            }
            catch (Exception ex)
            {
                ex.Dump(request);
            }
        }
Example #2
0
        /// <summary>
        /// This is called when the user is adding (or updating) a package source
        ///
        /// If this PROVIDER doesn't support user-defined package sources, remove this method.
        /// </summary>
        /// <param name="name">The name of the package source. If this parameter is null or empty the PROVIDER should use the location as the name (if the PROVIDER actually stores names of package sources)</param>
        /// <param name="location">The location (ie, directory, URL, etc) of the package source. If this is null or empty, the PROVIDER should use the name as the location (if valid)</param>
        /// <param name="trusted">A boolean indicating that the user trusts this package source. Packages returned from this source should be marked as 'trusted'</param>
        /// <param name="request">An object passed in from the PackageManagement that contains functions that can be used to interact with its Provider</param> 
        public void AddPackageSource(string name, string location, bool trusted, NuGetRequest request)
        {
            if (request == null){
                throw new ArgumentNullException("request");
            }
            try {
                request.Debug(string.Format(CultureInfo.InvariantCulture, "AddPackageSource - ProvidenName = '{0}', name='{1}', location='{2}', trusted='{3}'", PackageProviderName, name, location, trusted));

                // Error out if a user does not provide package source Name
                if (string.IsNullOrWhiteSpace(name))
                {
                    request.WriteError(ErrorCategory.InvalidArgument, Constants.Parameters.Name, Constants.Messages.MissingRequiredParameter, Constants.Parameters.Name);
                    return;
                }

                if (string.IsNullOrWhiteSpace(location))
                {
                    request.WriteError(ErrorCategory.InvalidArgument, Constants.Parameters.Location, Constants.Messages.MissingRequiredParameter, Constants.Parameters.Location);
                    return;
                }

                request.Debug(Resources.Messages.DebugInfoCallMethod, PackageProviderName, "GetOptionValue");
                // if this is supposed to be an update, there will be a dynamic parameter set for IsUpdatePackageSource
                var isUpdate = request.GetOptionValue(Constants.Parameters.IsUpdate).IsTrue();

                request.Debug(Resources.Messages.VariableCheck, "IsUpdate", isUpdate);

                // if your source supports credentials you get get them too:
                // string username =request.Username;
                // SecureString password = request.Password;
                // feel free to send back an error here if your provider requires credentials for package sources.

                // check first that we're not clobbering an existing source, unless this is an update

                request.Debug(Resources.Messages.DebugInfoCallMethod, PackageProviderName, string.Format(CultureInfo.InvariantCulture, "FindRegisteredSource -name'{0}'", name));

                var src = request.FindRegisteredSource(name);

                if (src != null && !isUpdate)
                {
                    // tell the user that there's one here already
                    request.WriteError(ErrorCategory.InvalidArgument, name, Constants.Messages.PackageSourceExists, name);
                    return;
                }

                // conversely, if it didn't find one, and it is an update, that's bad too:
                if (src == null && isUpdate)
                {
                    // you can't find that package source? Tell that to the user
                    request.WriteError(ErrorCategory.ObjectNotFound, name, Constants.Messages.UnableToResolveSource, name);
                    return;
                }

                // ok, we know that we're ok to save this source
                // next we check if the location is valid (if we support that kind of thing)

                var validated = false;

                if (!request.SkipValidate.Value)
                {
                    // the user has not opted to skip validating the package source location, so check if the source is valid
                    validated = request.ValidateSourceLocation(location);

                    if (!validated)
                    {
                        request.WriteError(ErrorCategory.InvalidData, name, Constants.Messages.SourceLocationNotValid, location);
                        return;
                    }

                    request.Verbose(Resources.Messages.SuccessfullyValidated, name);
                }

                // it's good to check just before you actually write something to see if the user has cancelled the operation
                if (request.IsCanceled)
                {
                    return;
                }

                // looking good -- store the package source.
                request.AddPackageSource(name, location, trusted, validated);

                // Yield the package source back to the caller.
                request.YieldPackageSource(name, location, trusted, true /*since we just registered it*/, validated);
            }
            catch (Exception e)
            {
                e.Dump(request);
            }
        }
        /// <summary>
        /// Download a single package to destination without checking for dependencies
        /// </summary>
        /// <param name="pkgItem"></param>
        /// <param name="request"></param>
        /// <param name="destLocation"></param>
        /// <returns></returns>
        internal static bool DownloadSinglePackage(PackageItem pkgItem, NuGetRequest request, string destLocation)
        {
            if (string.IsNullOrWhiteSpace(pkgItem.PackageFilename) || pkgItem.PackageSource == null || pkgItem.PackageSource.Location == null
            || (pkgItem.PackageSource.IsSourceAFile && pkgItem.Package == null))
            {
                request.WriteError(ErrorCategory.ObjectNotFound, pkgItem.Id, Constants.Messages.UnableToResolvePackage, pkgItem.Id);
                return false;
            }

            // this is if the user says -force
            bool force = request.GetOptionValue("Force") != null;

            // combine the path and the file name
            destLocation = Path.Combine(destLocation, pkgItem.PackageFilename);

            // if the file already exists
            if (File.Exists(destLocation))
            {
                // if no force, just return
                if (!force)
                {
                    request.Verbose(Constants.Messages.SkippedDownloadedPackage, pkgItem.Id);
                    request.YieldPackage(pkgItem, pkgItem.PackageSource.Name);
                    return true;
                }

                // here we know it is forced, so delete
                FileUtility.DeleteFile(destLocation, isThrow: false);

                // if after we try delete, it is still there, tells the user we can't perform the action
                if (File.Exists(destLocation))
                {
                    request.WriteError(ErrorCategory.ResourceUnavailable, destLocation, Constants.Messages.UnableToOverwriteExistingFile, destLocation);
                    return false;
                }
            }
            
            try
            {
                if (pkgItem.PackageSource.Repository.IsFile)
                {
                    using (var input = File.OpenRead(pkgItem.Package.FullFilePath))
                    {
                        using (var output = new FileStream(destLocation, FileMode.Create, FileAccess.Write, FileShare.Read))
                        {
                            input.CopyTo(output);
                        }
                    }
                }
                else
                {
                    //V2 download package protocol:
                    //sample url: http://www.nuget.org/api/v2/package/jQuery/2.1.3
                    string append = String.Format(CultureInfo.InvariantCulture, "/package/{0}/{1}", pkgItem.Id, pkgItem.Version);
                    string httpquery = PathUtility.UriCombine(pkgItem.PackageSource.Repository.Source, append);

                    NuGetClient.DownloadPackage(pkgItem.Id, pkgItem.Version, destLocation,
                        string.IsNullOrWhiteSpace(pkgItem.Package.ContentSrcUrl) ? httpquery : pkgItem.Package.ContentSrcUrl, request);
                }
            }
            catch (Exception ex)
            {
                ex.Dump(request);
                return false;
            }

            request.Verbose(Resources.Messages.SuccessfullyDownloaded, pkgItem.Id);
            request.YieldPackage(pkgItem, pkgItem.PackageSource.Name);

            return true;
        }
        /// <summary>
        ///     This is called when the user is adding (or updating) a package source
        ///     If this PROVIDER doesn't support user-defined package sources, remove this method.
        /// </summary>
        /// <param name="name">
        ///     The name of the package source. If this parameter is null or empty the PROVIDER should use the
        ///     location as the name (if the PROVIDER actually stores names of package sources)
        /// </param>
        /// <param name="location">
        ///     The location (ie, directory, URL, etc) of the package source. If this is null or empty, the
        ///     PROVIDER should use the name as the location (if valid)
        /// </param>
        /// <param name="trusted">
        ///     A boolean indicating that the user trusts this package source. Packages returned from this source
        ///     should be marked as 'trusted'
        /// </param>
        /// <param name="request">
        ///     An object passed in from the CORE that contains functions that can be used to interact with the
        ///     CORE and HOST
        /// </param>
        public void AddPackageSource(string name, string location, bool trusted, NuGetRequest request)
        {
            // Nice-to-have put a debug message in that tells what's going on.
            request.Debug("Calling '{0}::AddPackageSource' '{1}','{2}','{3}'", PackageProviderName, name, location, trusted);

            // if they didn't pass in a name, use the location as a name. (if you support that kind of thing)
            name = string.IsNullOrEmpty(name) ? location : name;

            // let's make sure that they've given us everything we need.
            if (string.IsNullOrEmpty(name)) {
                request.Error(ErrorCategory.InvalidArgument, Constants.Parameters.Name, Constants.Messages.MissingRequiredParameter, Constants.Parameters.Name);
                // we're done here.
                return;
            }

            if (string.IsNullOrEmpty(location)) {
                request.Error(ErrorCategory.InvalidArgument, Constants.Parameters.Location, Constants.Messages.MissingRequiredParameter, Constants.Parameters.Location);
                // we're done here.
                return;
            }

            // if this is supposed to be an update, there will be a dynamic parameter set for IsUpdatePackageSource
            var isUpdate = request.GetOptionValue(Constants.Parameters.IsUpdate).IsTrue();

            // if your source supports credentials you get get them too:
            // string username =request.Username;
            // SecureString password = request.Password;
            // feel free to send back an error here if your provider requires credentials for package sources.

            // check first that we're not clobbering an existing source, unless this is an update

            var src = request.FindRegisteredSource(name);

            if (src != null && !isUpdate) {
                // tell the user that there's one here already
                request.Error(ErrorCategory.InvalidArgument, name ?? location, Constants.Messages.PackageSourceExists, name ?? location);
                // we're done here.
                return;
            }

            // conversely, if it didn't find one, and it is an update, that's bad too:
            if (src == null && isUpdate) {
                // you can't find that package source? Tell that to the user
                request.Error(ErrorCategory.ObjectNotFound, name ?? location, Constants.Messages.UnableToResolveSource, name ?? location);
                // we're done here.
                return;
            }

            // ok, we know that we're ok to save this source
            // next we check if the location is valid (if we support that kind of thing)

            var validated = false;

            if (!request.SkipValidate) {
                // the user has not opted to skip validating the package source location, so check that it's valid (talk to the url, or check if it's a valid directory, etc)
                // todo: insert code to check if the source is valid

                validated = request.ValidateSourceLocation(location);

                if (!validated) {
                    request.Error(ErrorCategory.InvalidData, name ?? location, Constants.Messages.SourceLocationNotValid, location);
                    // we're done here.
                    return;
                }

                // we passed validation!
            }

            // it's good to check just before you actaully write something to see if the user has cancelled the operation
            if (request.IsCanceled) {
                return;
            }

            // looking good -- store the package source
            // todo: create the package source (and store it whereever you store it)

            request.Verbose("Storing package source {0}", name);

            // actually yielded by the implementation.
            request.AddPackageSource(name, location, trusted, validated);

            // and, before you go, Yield the package source back to the caller.
            if (!request.YieldPackageSource(name, location, trusted, true /*since we just registered it*/, validated)) {
                // always check the return value of a yield, since if it returns false, you don't keep returning data
                // this can happen if they have cancelled the operation.
                return;
            }
            // all done!
        }
Example #5
0
        /// <summary>
        /// Returns the package dependencies of packageItem. We only return the dependencies that are not installed in the destination folder of request
        /// </summary>
        /// <param name="packageItem"></param>
        /// <param name="processedDependencies"></param>
        /// <param name="request"></param>
        private static IEnumerable<PackageItem> GetPackageDependenciesHelper(PackageItem packageItem, HashSet<string> processedDependencies, NuGetRequest request)
        {
            if (packageItem.Package.DependencySetList == null)
            {
                yield break;
            }

            bool force = request.GetOptionValue("Force") != null;
            foreach (var depSet in packageItem.Package.DependencySetList)
            {
                if (depSet.Dependencies == null)
                {
                    continue;
                }

                foreach (var dep in depSet.Dependencies)
                {
                    var depKey = string.Format(CultureInfo.InvariantCulture, "{0}!#!{1}", dep.Id, dep.DependencyVersion.ToStringSafe());

                    if (processedDependencies.Contains(depKey))
                    {
                        continue;
                    }

                    // Get the min dependencies version
                    string minVersion = dep.DependencyVersion.MinVersion.ToStringSafe();

                    // Get the max dependencies version
                    string maxVersion = dep.DependencyVersion.MaxVersion.ToStringSafe();

                    if (!force)
                    {
                        bool installed = false;

                        var installedPackages = request.InstalledPackages.Value;

                        if (request.InstalledPackages.Value.Count() > 0)
                        {
                            // check the installedpackages options passed in
                            foreach (var installedPackage in request.InstalledPackages.Value)
                            {
                                // if name not match, move on to the next entry
                                if (!string.Equals(installedPackage.Id, dep.Id, StringComparison.OrdinalIgnoreCase))
                                {
                                    continue;
                                }

                                // if no version and if name matches, skip
                                if (string.IsNullOrWhiteSpace(installedPackage.Version))
                                {
                                    // skip this dependency
                                    installed = true;
                                    break;
                                }

                                SemanticVersion packageVersion = new SemanticVersion(installedPackage.Version);

                                // checks min and max
                                if (request.MinAndMaxVersionMatched(packageVersion, minVersion, maxVersion, dep.DependencyVersion.IsMinInclusive, dep.DependencyVersion.IsMaxInclusive))
                                {
                                    // skip this dependency
                                    installed = true;
                                    break;
                                }
                            }
                        }
                        // check whether package is installed at destination. only used this option if installedpackages not passed in
                        else if (request.GetInstalledPackages(dep.Id, null, minVersion, maxVersion, minInclusive: dep.DependencyVersion.IsMinInclusive, maxInclusive: dep.DependencyVersion.IsMaxInclusive, terminateFirstFound: true))
                        {
                            installed = true;
                        }

                        if (installed)
                        {
                            // already processed this so don't need to do this next time
                            processedDependencies.Add(dep.Id);
                            request.Verbose(String.Format(CultureInfo.CurrentCulture, Messages.AlreadyInstalled, dep.Id));
                            // already have a dependency so move on
                            continue;
                        }
                    }

                    // get all the packages that match this dependency
                    var dependentPackageItem = request.GetPackageById(dep.Id, request, minimumVersion: minVersion, maximumVersion: maxVersion, minInclusive: dep.DependencyVersion.IsMinInclusive, maxInclusive: dep.DependencyVersion.IsMaxInclusive).ToArray();

                    if (dependentPackageItem.Length == 0)
                    {
                        request.WriteError(ErrorCategory.ObjectNotFound, dep.Id, Constants.Messages.UnableToFindDependencyPackage, dep.Id);

                        break;
                    }

                    // Get the package that is the latest version
                    yield return dependentPackageItem.OrderByDescending(each => each.Version).FirstOrDefault();

                    processedDependencies.Add(depKey);
                }
            }
        }