This class drives the Request class that is an interface exposed from the PackageManagement Platform to the provider to use.
Inheritance: Request
Example #1
0
        /// <summary>
        /// Find the package via the given uri query.
        /// </summary>
        /// <param name="query">A full Uri. A sample Uri looks like "http://www.nuget.org/api/v2/FindPackagesById()?id='Jquery'" </param>
        /// <param name="request">An object passed in from the PackageManagement that contains functions that can be used to interact with its Provider</param> 
        /// <returns>Package objects</returns>
        internal static IEnumerable<PackageBase> FindPackage(string query, NuGetRequest request) {
            request.Debug(Messages.DebugInfoCallMethod, "NuGetClient", "FindPackage");

            request.Verbose(Messages.SearchingRepository, query, "");

            return HttpClientPackageRepository.SendRequest(query, request);
        }
        /// <summary>
        /// Ctor's
        /// </summary>
        /// <param name="request">The nuget request object</param>
        /// <param name="queryUrl">Packagesource location</param>
        internal HttpClientPackageRepository(string queryUrl, NuGetRequest request)
        {
            // Validate the url

            Uri newUri;
            Uri validatedUri = null;

            if (Uri.TryCreate(queryUrl, UriKind.Absolute, out newUri))
            {
                validatedUri = NuGetPathUtility.ValidateUri(newUri, request);
            }

            if (validatedUri == null)
            {
                throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Messages.InvalidQueryUrl, queryUrl));
            }

            queryUrl = validatedUri.AbsoluteUri;

            // if a query is http://www.nuget.org/api/v2 then we add / to the end
            if (!queryUrl.EndsWith("/", StringComparison.OrdinalIgnoreCase))
            {
                queryUrl = String.Concat(queryUrl, "/");
            }

            _queryUri = queryUrl;

            //we are constructing the url query like http://www.nuget.org/api/v2/FindPackagesById()?id='JQuery'
            _nugetFindPackageIdQueryFormat = PathUtility.UriCombine(_queryUri, NuGetConstant.FindPackagesById);
        }
        /// <summary>
        /// Performs one-time initialization of the $provider.
        /// </summary>
        /// <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 InitializeProvider(NuGetRequest request)
        {
            if (request == null){
                throw new ArgumentNullException("request");
            }

            request.Debug(Resources.Messages.DebugInfoCallMethod, PackageProviderName, "InitializeProvider");
        }            
Example #4
0
        /// <summary>
        /// Returns the validated uri. Returns null if we cannot validate it
        /// </summary>
        /// <param name="query"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        internal static Uri ValidateUri(Uri query, NuGetRequest request)
        {
            var client = request.ClientWithoutAcceptHeader;

            var response = PathUtility.GetHttpResponse(client, query.AbsoluteUri, (() => request.IsCanceled),
                ((msg, num) => request.Verbose(Resources.Messages.RetryingDownload, msg, num)), (msg) => request.Verbose(msg), (msg) => request.Debug(msg));

            if (response == null)
            {
                return null;
            }

            // if response is not success, we need to check for redirection
            if (!response.IsSuccessStatusCode)
            {
                // Check for redirection (http status code 3xx)
                if (response.StatusCode == HttpStatusCode.MultipleChoices || response.StatusCode == HttpStatusCode.MovedPermanently
                    || response.StatusCode == HttpStatusCode.Found || response.StatusCode == HttpStatusCode.SeeOther
                    || response.StatusCode == HttpStatusCode.TemporaryRedirect)
                {
                    // get the redirected direction
                    string location = response.Headers.GetValues("Location").FirstOrDefault();
                    if (String.IsNullOrWhiteSpace(location))
                    {
                        return null;
                    }

                    // make a new query based on location
                    query = new Uri(location);
                }
                else
                {
                    // other status code is wrong
                    return null;
                }
            }
            else
            {
                query = new Uri(response.RequestMessage.RequestUri.AbsoluteUri);
            }

            //Making a query like: www.nuget.org/api/v2/FindPackagesById()?id='FoooBarr' to check the server available. 
            //'FoooBarr' is an any random package id
            string queryUri = "FoooBarr".MakeFindPackageByIdQuery(PathUtility.UriCombine(query.AbsoluteUri, NuGetConstant.FindPackagesById));

            response = PathUtility.GetHttpResponse(client, queryUri, (() => request.IsCanceled),
                ((msg, num) => request.Verbose(Resources.Messages.RetryingDownload, msg, num)), (msg) => request.Verbose(msg), (msg) => request.Debug(msg));


            // The link is not valid
            if (response == null || !response.IsSuccessStatusCode)
            {
                return null;
            }

            return query;
        }
Example #5
0
        internal static bool ValidateSourceUri(IEnumerable<string> supportedSchemes, Uri srcUri, NuGetRequest request)
        {
            if (!supportedSchemes.Contains(srcUri.Scheme.ToLowerInvariant()))
            {
                return false;
            }

            if (srcUri.IsFile)
            {
                //validate file source location
                if (Directory.Exists(srcUri.LocalPath))
                {
                    return true;
                }
                return false;
            }

            //validate uri source location
            return ValidateUri(srcUri, request) != null;
        }
        public virtual IPackageRepository CreateRepository(string packageSource, NuGetRequest request)
        {
            if (packageSource == null)
            {
                throw new ArgumentNullException("packageSource");
            }

            // we cannot call new uri on file path on linux because it will error out
            if (System.IO.Directory.Exists(packageSource))
            {
                return new LocalPackageRepository(packageSource, request);
            }

            Uri uri = new Uri(packageSource);

            if (uri.IsFile)
            {
                return new LocalPackageRepository(uri.LocalPath, request);
            }

            return new HttpClientPackageRepository(packageSource, request);
        }
        private IEnumerable<PackageItem> GetPackageById(PackageSource source, 
            string name,
            NuGetRequest request, 
            string requiredVersion = null, 
            string minimumVersion = null, 
            string maximumVersion = null,
            bool minInclusive = true,
            bool maxInclusive = true)
        {
            try {
                Debug(Resources.Messages.DebugInfoCallMethod3, "NuGetRequest", "GetPackageById", name);

                // source should be attached to a repository
                if (source.Repository == null)
                {
                    return Enumerable.Empty<PackageItem>();
                }

                // otherwise fall back to traditional behavior
                var pkgs = source.Repository.FindPackagesById(name, request);

                // exact version is required if required version is not null or empty OR maxversion == minversion and min and max inclusive are true
                bool exactVersionRequired = (!string.IsNullOrWhiteSpace(requiredVersion))
                    || (!string.IsNullOrWhiteSpace(maximumVersion)
                        && !string.IsNullOrWhiteSpace(minimumVersion)
                        && (new SemanticVersion(minimumVersion) == new SemanticVersion(maximumVersion))
                        && minInclusive && maxInclusive);

                // if required version not specified then don't use unlisted version
                // unlisted version is the one that has published year as 1900
                if (!exactVersionRequired)
                {
                    pkgs = pkgs.Where(pkg => pkg.Published.HasValue && pkg.Published.Value.Year > 1900);
                }

                if (AllVersions.Value){
                    //Display versions from lastest to oldest
                    pkgs = (from p in pkgs select p).OrderByDescending(x => x.Version);
                }
                else if (String.IsNullOrWhiteSpace(requiredVersion) && String.IsNullOrWhiteSpace(minimumVersion) && String.IsNullOrWhiteSpace(maximumVersion))
                {

                    if (AllowPrereleaseVersions.Value || source.Repository.IsFile) {
                        //Handling something like Json.NET 7.0.1-beta3 as well as local repository
                        pkgs = from p in pkgs
                            group p by p.Id
                            into newGroup
                                   select newGroup.Aggregate((current, next) => (next.Version > current.Version) ? next : current);

                    } else {
                        pkgs = from p in pkgs where p.IsLatestVersion select p;
                    }
                }
                else if (!exactVersionRequired && !AllowPrereleaseVersions.Value)
                {
                    // if exact version is not required and allow prerelease is false, we will have to filter out prerelease version
                    pkgs = from p in pkgs where string.IsNullOrWhiteSpace(p.Version.SpecialVersion) select p;
                }

                pkgs = FilterOnContains(pkgs);
                pkgs = FilterOnTags(pkgs);

                var results = FilterOnVersion(pkgs, requiredVersion, minimumVersion, maximumVersion, minInclusive, maxInclusive)
                    .Select(pkg => new PackageItem {
                        Package = pkg,
                        PackageSource = source,
                        FastPath = MakeFastPath(source, pkg.Id, pkg.Version.ToString())
                    });
                return results;
            } catch (Exception e) {
                e.Dump(this);
                return Enumerable.Empty<PackageItem>();
            }
        }
        /// <summary>
        /// Get the package based on given package id
        /// </summary>
        /// <param name="name">Package id or name</param>
        /// <param name="requiredVersion"></param>
        /// <param name="minimumVersion"></param>
        /// <param name="maximumVersion"></param>
        /// <param name="maxInclusive"></param>
        /// <param name="minInclusive"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        internal IEnumerable<PackageItem> GetPackageById(string name, NuGetRequest request, string requiredVersion = null,
            string minimumVersion = null, string maximumVersion = null, bool minInclusive = true, bool maxInclusive = true)
        {
            if (String.IsNullOrWhiteSpace(name))
            {
                return Enumerable.Empty<PackageItem>();
            }

            return SelectedSources.AsParallel().WithMergeOptions(ParallelMergeOptions.NotBuffered).SelectMany(source => GetPackageById(source, name, request, requiredVersion, minimumVersion, maximumVersion, minInclusive, maxInclusive));
        }
        /// <summary>
        /// Search the entire repository for the case when a user does not provider package name or uses wildcards in the name.
        /// </summary>
        /// <param name="searchTerm"></param>
        /// <param name="nugetRequest"></param>
        /// <returns></returns>
        public IEnumerable<IPackage> Search(string searchTerm, NuGetRequest nugetRequest)
        {
            if (nugetRequest == null)
            {
                yield break;
            }

            nugetRequest.Debug(Messages.DebugInfoCallMethod3, "HttpClientPackageRepository", "Search", searchTerm);

            var searchQuery = searchTerm.MakeSearchQuery(_queryUri, nugetRequest.AllowPrereleaseVersions.Value, nugetRequest.AllVersions.Value);

            foreach (var pkg in SendRequest(searchQuery, nugetRequest))
            {
                yield return pkg;
            }
        }
        private IEnumerable<IPackage> SearchImpl(string searchTerm, NuGetRequest nugetRequest)
        {
            if (nugetRequest == null) {
                yield break;
            }

            nugetRequest.Debug(Resources.Messages.SearchingRepository, "LocalPackageRepository", Source);

            var files = Directory.GetFiles(Source);

            foreach (var package in nugetRequest.FilterOnTags(files.Select(nugetRequest.GetPackageByFilePath).Where(pkgItem => pkgItem != null).Select(pkg => pkg.Package)))
            {
                yield return package;
            }

            // look in the package source location for directories that contain nupkg files.
            var subdirs = Directory.EnumerateDirectories(Source, "*", SearchOption.AllDirectories);
            foreach (var subdir in subdirs) {
                var nupkgs = Directory.EnumerateFileSystemEntries(subdir, "*.nupkg", SearchOption.TopDirectoryOnly);

                foreach (var package in nugetRequest.FilterOnTags(nupkgs.Select(nugetRequest.GetPackageByFilePath).Where(pkgItem => pkgItem != null).Select(pkg => pkg.Package)))
                {
                    yield return package;
                }
            }
        }
        /// <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 #12
0
        /// <summary>
        /// Finds packages given a locally-accessible filename
        ///
        /// Package information must be returned using <c>request.YieldPackage(...)</c> function.
        /// </summary>
        /// <param name="file">the full path to the file to determine if it is a package</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 FindPackageByFile(string file, int id, NuGetRequest request)
        {
            if (request == null){
                throw new ArgumentNullException("request");
            }

            request.Debug(Resources.Messages.DebugInfoCallMethod3, PackageProviderName, file, id);

            var pkgItem = request.GetPackageByFilePath(Path.GetFullPath(file));
            if (pkgItem != null)
            {
                request.YieldPackage(pkgItem, file);
            }
        }
Example #13
0
        /// <summary>
        /// Removes/Unregisters a package source
        /// </summary>
        /// <param name="name">The name or location of a package source to remove.</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 RemovePackageSource(string name, NuGetRequest request)
        {
            if (request == null){
                throw new ArgumentNullException("request");
            }
            request.Debug(Resources.Messages.DebugInfoCallMethod, PackageProviderName, "RemovePackageSource");

            var src = request.FindRegisteredSource(name);
            if (src == null)
            {
                request.Warning(Constants.Messages.UnableToResolveSource, name);
                return;
            }

            request.RemovePackageSource(src.Name);
            request.YieldPackageSource(src.Name, src.Location, src.Trusted, false, src.IsValidated);
        }
Example #14
0
 internal static void Dump(this Exception ex, NuGetRequest request)
 {
     request.Debug(ex.ToString());
 }
        /// <summary>
        /// Find-Package
        /// </summary>
        /// <param name="openPackage">Delegate function which is actually finding a package</param>
        /// <param name="packageId">Package Id</param>
        /// <param name="version">Package version</param>
        /// <param name="nugetRequest"></param>
        /// <returns></returns>
        private IPackage FindPackage(Func<string, Request, IPackage> openPackage, string packageId, SemanticVersion version, NuGetRequest nugetRequest)
        {
            if (nugetRequest == null) {
                return null;
            }

            nugetRequest.Debug(Resources.Messages.SearchingRepository, "FindPackage", packageId);

            var lookupPackageName = new PackageName(packageId, version);

            //handle file cache here if we want to support local package cache later

            // Lookup files which start with the name "<Id>." and attempt to match it with all possible version string combinations (e.g. 1.2.0, 1.2.0.0)
            // before opening the package. To avoid creating file name strings, we attempt to specifically match everything after the last path separator
            // which would be the file name and extension.
            return (from path in GetPackageLookupPaths(packageId, version)
                    let package = GetPackage(openPackage, path, nugetRequest)
                where lookupPackageName.Equals(new PackageName(package.Id, package.Version))
                select package).FirstOrDefault();
        }
        /// <summary>
        /// Search the entire repository for the case when a user does not provider package name or uses wildcards in the name.
        /// </summary>
        /// <param name="searchTerm">The Searchterm</param>
        /// <param name="nugetRequest"></param>
        /// <returns></returns>
        public IEnumerable<IPackage> Search(string searchTerm, NuGetRequest nugetRequest)
        {
            var packages = SearchImpl(searchTerm, nugetRequest);
            if (packages == null) {
                return Enumerable.Empty<IPackage>();
            }

            if (nugetRequest != null && nugetRequest.AllVersions.Value) {
                //return whatever we can find
                return packages;
            }

            //return the latest version
            return packages.GroupBy(p => p.Id).Select(each => each.OrderByDescending(pp => pp.Version).FirstOrDefault());
        }
 /// <summary>
 /// Find-Package based the given Id
 /// </summary>
 /// <param name="packageId">Package Id</param>
 /// <param name="request"></param>
 /// <returns></returns>
 public IEnumerable<IPackage> FindPackagesById(string packageId, NuGetRequest request)
 {
     return FindPackagesById(OpenPackage, packageId, request);
 }
 /// <summary>
 /// Find-Package
 /// </summary>
 /// <param name="packageId">Package id</param>
 /// <param name="version">Package Name</param>
 /// <param name="request"></param>
 /// <returns></returns>
 public virtual IPackage FindPackage(string packageId, SemanticVersion version, NuGetRequest request)
 {
     return FindPackage(OpenPackage, packageId, version, request);
 }
Example #19
0
        /// <summary>
        /// Resolves and returns Package Sources to the client.
        ///
        /// Specified sources are passed in via the request object (<c>request.GetSources()</c>).
        ///
        /// Sources are returned using <c>request.YieldPackageSource(...)</c>
        /// </summary>
        /// <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 ResolvePackageSources(NuGetRequest request)
        {
            if (request == null){
                throw new ArgumentNullException("request");
            }

            request.Debug(Resources.Messages.DebugInfoCallMethod, PackageProviderName, "ResolvePackageSources");

            var selectedSources = request.SelectedSources;

            try
            {
                foreach (var source in selectedSources)
                {
                    request.Debug(Resources.Messages.YieldingPackageSource, PackageProviderName, source);
                    request.YieldPackageSource(source.Name, source.Location, source.Trusted, source.IsRegistered, source.IsValidated);
                }
            }
            catch (Exception e)
            {
                e.Dump(request);
            }

            request.Debug(Resources.Messages.DebugInfoReturnCall, PackageProviderName,  "ResolvePackageSources");
        }
Example #20
0
        /// <summary>
        /// Installs a given package.
        /// </summary>
        /// <param name="fastPackageReference">A provider supplied identifier that specifies an exact package</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 InstallPackage(string fastPackageReference, NuGetRequest request) 
        {
            if (request == null){
                throw new ArgumentNullException("request");
            }

            request.Debug(Resources.Messages.DebugInfoCallMethod3, PackageProviderName, "InstallPackage", fastPackageReference);

            try {

                var pkgItem = request.GetPackageByFastpath(fastPackageReference);
                if (pkgItem == null) {
                    request.WriteError(ErrorCategory.InvalidArgument, fastPackageReference, Constants.Messages.UnableToResolvePackage);
                    return;
                }

                if ((pkgItem.PackageSource == null) || (pkgItem.PackageSource.Location == null) || (pkgItem.Package == null)) {
                    request.Debug(Resources.Messages.VariableCheck, "PackageSource or PackageSource.Location or Package object", "null");
                    request.WriteError(ErrorCategory.ObjectNotFound, fastPackageReference, Constants.Messages.UnableToResolvePackage, pkgItem.Id);
                    return;
                }

                request.Debug(Resources.Messages.VariableCheck, "Package version", pkgItem.Version);
                request.Debug(Resources.Messages.VariableCheck, "Request's Destination", request.Destination);

                // got this far, let's install the package we came here for.
                if (!NuGetClient.InstallOrDownloadPackageHelper(pkgItem, request, Constants.Install,
                    (packageItem, progressTracker) => NuGetClient.InstallSinglePackage(packageItem, request, progressTracker)))
                {
                    // package itself didn't install. Write error
                    request.WriteError(ErrorCategory.InvalidResult, pkgItem.Id, Constants.Messages.PackageFailedInstallOrDownload, pkgItem.Id, CultureInfo.CurrentCulture.TextInfo.ToLower(Constants.Install));

                    return;
                }
            } catch (Exception ex) {
                ex.Dump(request);
                request.WriteError(ErrorCategory.InvalidOperation, fastPackageReference, ex.Message);
            }
        }
Example #21
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);
            }
        }
Example #22
0
        /// <summary>
        /// Returns the packages that are installed. This method is called when a user type get-package, install-package and uninstall-package.
        /// </summary>
        /// <param name="name">the package name to match. Empty or null means match everything</param>
        /// <param name="requiredVersion">the specific version asked for. If this parameter is specified (ie, not null or empty string) then the minimum and maximum values are ignored</param>
        /// <param name="minimumVersion">the minimum version of packages to return . If the <code>requiredVersion</code> parameter is specified (ie, not null or empty string) this should be ignored</param>
        /// <param name="maximumVersion">the maximum version of packages to return . If the <code>requiredVersion</code> parameter is specified (ie, not null or empty string) this should be ignored</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 GetInstalledPackages(string name, string requiredVersion, string minimumVersion, string maximumVersion, NuGetRequest request) 
        {
            if (request == null){
                throw new ArgumentNullException("request");
            }

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

            // 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))
            {
                // A user provides the version info but missing name
                if (string.IsNullOrWhiteSpace(name))
                {
                    request.Warning(Constants.Messages.MissingRequiredParameter, "name");
                    return;
                }

                // A user provides the version info but the name containing wildcards
                if (WildcardPattern.ContainsWildcardCharacters(name)) {
                    return;
                }
            }

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

            request.GetInstalledPackages(name, requiredVersion, minimumVersion, maximumVersion);
        }
Example #23
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);
            }
        }
 /// <summary>
 /// Ctor's
 /// </summary>
 /// <param name="request"></param>
 /// <param name="physicalPath"></param>
 public LocalPackageRepository(string physicalPath, NuGetRequest request)
 {
     _path = physicalPath;
 }
Example #25
0
        /// <summary>
        /// Downloads a remote package file to a local location.
        /// </summary>
        /// <param name="fastPackageReference"></param>
        /// <param name="destLocation"></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 DownloadPackage(string fastPackageReference, string destLocation, NuGetRequest request)
        {
            if (request == null){
                throw new ArgumentNullException("request");
            }

            request.Debug(Resources.Messages.DebugInfoCallMethod3, PackageProviderName, fastPackageReference, destLocation);

            try {
                var pkgItem = request.GetPackageByFastpath(fastPackageReference);
                if (pkgItem == null) {
                    request.WriteError(ErrorCategory.InvalidArgument, fastPackageReference, Constants.Messages.UnableToResolvePackage);
                    return;
                }

                NuGetClient.InstallOrDownloadPackageHelper(pkgItem, request, Constants.Download,
                    (packageItem, progressTracker) => NuGetClient.DownloadSinglePackage(packageItem, request, destLocation, progressTracker));
            } catch (Exception ex) {
                ex.Dump(request);
                request.WriteError(ErrorCategory.InvalidOperation, fastPackageReference, ex.Message);
            }
        }
        /// <summary>
        /// Send the request to the server with buffer size to account for the case where there are more data
        /// that we need to fetch
        /// </summary>
        /// <param name="query"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        public static IEnumerable<PackageBase> SendRequest(string query, NuGetRequest request)
        {
            const int bufferSize = 40;
            // number of threads sending the requests
            const int numberOfSenders = 4;

            var startPoint = 0;
            var tasks = new List<Task<Stream>>();

            bool stopSending = false;
            object stopLock = new Object();

            // Send one request first

            // this initial query is of the form http://www.nuget.org/api/v2/FindPackagesById()?id='jquery'&$skip={0}&$top={1}
            UriBuilder initialQuery = new UriBuilder(query.InsertSkipAndTop());

            PackageBase firstPackage = null;

            // Send out an initial request
            // we send out 1 initial request first to check for redirection and check whether repository supports odata
            using (Stream stream = NuGetClient.InitialDownloadDataToStream(initialQuery, startPoint, bufferSize, request))
            {
                if (stream == null)
                {
                    yield break;
                }

                XDocument document = XmlUtility.LoadSafe(stream, ignoreWhiteSpace: true);

                var entries = document.Root.ElementsNoNamespace("entry").ToList();

                // If the initial request has different number of entries than the buffer size, return it because this means the server
                // does not understand odata request or there is no more data. in the former case, we have to stop to prevent infinite loop
                if (entries.Count != bufferSize)
                {
                    request.Debug(Messages.PackagesReceived, entries.Count);
                    stopSending = true;
                }

                foreach (XElement entry in entries)
                {
                    var package = new PackageBase();

                    // set the first package of the request. this is used later to verify that the case when the number of packages in the repository
                    // is the same as the buffer size and the repository does not support odata query. in that case, we want to check whether the first package
                    // exists anywhere in the second call. if it is, then we cancel the request (this is to prevent infinite loop)
                    if (firstPackage == null)
                    {
                        firstPackage = package;
                    }

                    PackageUtility.ReadEntryElement(ref package, entry);
                    yield return package;
                }
            }

            if (stopSending || request.IsCanceled)
            {
                yield break;
            }

            // To avoid more redirection (for example, if the initial query is nuget.org, it will be changed to www.nuget.org

            query = initialQuery.Uri.ToString();

            // Sending the initial requests
            for (var i = 0; i < numberOfSenders; i++)
            {
                // Update the start point to fetch the packages
                startPoint += bufferSize;

                // Get the query
                var newQuery = string.Format(query, startPoint, bufferSize);

                // Send it
                tasks.Add(Task.Factory.StartNew(() =>
                {
                    Stream items = NuGetClient.DownloadDataToStream(newQuery, request);
                    return items;
                }));
            }

            //Wait for the responses, parse the data, and send to the user
            while (tasks.Count > 0)
            {

                //Cast because the compiler warning: Co-variant array conversion from Task[] to Task[] can cause run-time exception on write operation.
                var index = Task.WaitAny(tasks.Cast<Task>().ToArray());

                using (Stream stream = tasks[index].Result)
                {
                    if (stream == null)
                    {
                        yield break;
                    }

                    XDocument document = XmlUtility.LoadSafe(stream, ignoreWhiteSpace: true);

                    var entries = document.Root.ElementsNoNamespace("entry").ToList();

                    if (entries.Count < bufferSize)
                    {
                        request.Debug(Messages.PackagesReceived, entries.Count);
                        lock (stopLock)
                        {
                            stopSending = true;
                        }
                    }

                    foreach (XElement entry in entries)
                    {
                        var package = new PackageBase();

                        PackageUtility.ReadEntryElement(ref package, entry);

                        if (firstPackage != null)
                        {
                            // check whether first package in the first request exists anywhere in the second request
                            if (string.Equals(firstPackage.GetFullName(), package.GetFullName(), StringComparison.OrdinalIgnoreCase)
                                && string.Equals(firstPackage.Version, package.Version, StringComparison.OrdinalIgnoreCase))
                            {
                                lock (stopLock)
                                {
                                    stopSending = true;
                                }

                                break;
                            }
                        }

                        yield return package;
                    }

                    // we only needs to check for the existence of the first package in the second request. don't need to do for subsequent request
                    if (firstPackage != null)
                    {
                        firstPackage = null;
                    }
                }

                // checks whether we should stop sending requests
                if (!stopSending && !request.IsCanceled)
                {
                    // Make sure nobody else is updating the startPoint
                    lock (stopLock)
                    {
                        // update the startPoint
                        startPoint += bufferSize;
                    }
                    // Make a new request with the new startPoint
                    var newQuery = string.Format(query, startPoint, bufferSize);

                    //Keep sending a request
                    tasks[index] = (Task.Factory.StartNew(searchQuery =>
                    {
                        var items = NuGetClient.DownloadDataToStream(searchQuery.ToStringSafe(), request);
                        return items;
                    }, newQuery));

                }
                else
                {
                    if (request.IsCanceled)
                    {
                        request.Warning(Messages.RequestCanceled, "HttpClientPackageRepository", "SendRequest");
                        //stop sending request to the remote server
                        stopSending = true;
                    }

                    tasks.RemoveAt(index);
                }
            }
        }
Example #27
0
        /// <summary>
        /// Uninstalls a package
        /// </summary>
        /// <param name="fastPackageReference"></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 UninstallPackage(string fastPackageReference, NuGetRequest request)
        {
            if (request == null){
                throw new ArgumentNullException("request");
            }

            request.Debug(Resources.Messages.DebugInfoCallMethod3, PackageProviderName, "UninstallPackage", fastPackageReference);

            var pkg = request.GetPackageByFastpath(fastPackageReference);

            NuGetClient.UninstallPackage(request, pkg);
        }
        /// <summary>
        /// Find-Package
        /// </summary>
        /// <param name="packageId">package Id</param>
        /// <param name="version">package version</param>
        /// <param name="request"></param>
        /// <returns></returns>
        public IPackage FindPackage(string packageId, SemanticVersion version, NuGetRequest request)
        {
            if (string.IsNullOrWhiteSpace(packageId)) {
                return null;
            }

            request.Debug(Messages.DebugInfoCallMethod3, "HttpClientPackageRepository", "FindPackage", packageId);

            var query = packageId.MakeFindPackageByIdQuery(_nugetFindPackageIdQueryFormat);

            var packages = NuGetClient.FindPackage(query, request);

            //Usually versions has a limited number, ToArray should be ok.
            var versions = version.GetComparableVersionStrings().ToArray();

            //Will only enumerate packages once
            return packages.FirstOrDefault(package => packageId.Equals(package.Id, StringComparison.OrdinalIgnoreCase) && versions.Contains(package.Version,StringComparer.OrdinalIgnoreCase));
        }
Example #29
0
        private static void NormalizeVersion(NuGetRequest request, ref string requiredVersion, ref string minimumVersion, ref string maximumVersion) {
            if (!string.IsNullOrWhiteSpace(requiredVersion))
            {
                requiredVersion = requiredVersion.FixVersion();
                minimumVersion = null;
                maximumVersion = null;
            }
            else
            {
                if (!string.IsNullOrWhiteSpace(minimumVersion))
                {
                    minimumVersion = minimumVersion.FixVersion();
                }

                if (!string.IsNullOrWhiteSpace(maximumVersion))
                {
                    maximumVersion = maximumVersion.FixVersion();
                }
            }

            if (!string.IsNullOrWhiteSpace(minimumVersion) && !string.IsNullOrWhiteSpace(maximumVersion))
            {
                if(new SemanticVersion(minimumVersion) > new SemanticVersion(maximumVersion))
                {
                    request.Warning("Specified version range is invalid. minimumVersion = {0} maximumVersion ={1}", minimumVersion, maximumVersion);
                }
            }
        }
        /// <summary>
        /// Find-Package bases on the given package Id
        /// </summary>
        /// <param name="packageId">Package Id</param>
        /// <param name="request"></param>
        /// <returns></returns>
        public IEnumerable<IPackage> FindPackagesById(string packageId, NuGetRequest request)
        {
            request.Debug(Messages.DebugInfoCallMethod3, "HttpClientPackageRepository", "FindPackagesById", packageId);

            var query = packageId.MakeFindPackageByIdQuery(_nugetFindPackageIdQueryFormat);

            //request.Verbose(query.ToString());

            return NuGetClient.FindPackage(query, request);
        }