/// <summary>
        /// Add a scoped registries.
        /// </summary>
        /// <param name="registries">Registries to add to the manifest.</param>
        /// <returns>true if the registries are added to the manifest, false otherwise.</returns>
        internal bool AddRegistries(IEnumerable <PackageManagerRegistry> registries)
        {
            List <object> scopedRegistries;

            try {
                scopedRegistries = ScopedRegistries;
            } catch (ParseException exception) {
                Logger.Log(String.Format("{0}  Unable to add registries:\n",
                                         exception.ToString(),
                                         PackageManagerRegistry.ToString(registries)),
                           level: LogLevel.Error);
                return(false);
            }
            if (scopedRegistries == null)
            {
                scopedRegistries = new List <object>();
                manifestDict[MANIFEST_SCOPED_REGISTRIES_KEY] = scopedRegistries;
            }
            RemoveRegistries(registries, displayWarning: false);
            foreach (var registry in registries)
            {
                scopedRegistries.Add(new Dictionary <string, object>()
                {
                    { MANIFEST_REGISTRY_NAME_KEY, registry.Name },
                    { MANIFEST_REGISTRY_URL_KEY, registry.Url },
                    { MANIFEST_REGISTRY_SCOPES_KEY, registry.Scopes }
                });
            }
            return(true);
        }
        /// <summary>
        /// Apply registry changes to the projects manifest.
        /// </summary>
        /// <param name="manifestModifier">Object that modifies the project's manifest.</param>
        /// <param name="availableRegistries">Registries that are available in the
        /// configuration.</param>
        /// <param name="manifestRegistries">Registries that are present in the manifest.</param>
        /// <param name="selectedRegistryUrls">URLs of selected registries, these should be items in
        /// availableRegistries.</param>
        /// <param name="addRegistries">Whether to add selected registries to the manifest.</param>
        /// <param name="removeRegistries">Whether to remove unselected registries from the
        /// manifest.</param>
        /// <param name="invertSelection">If false, adds the selected registries and removes the
        /// unselected registries.  If true, removes the selected registries and adds the unselected
        /// registries.</param>
        /// <param name="addedRegistries">If specified, is extended with the list of registries added
        /// to the manifest.<param>
        /// <returns>true if successful, false otherwise.</returns>
        private static bool SyncRegistriesToManifest(
            PackageManifestModifier manifestModifier,
            Dictionary <string, PackageManagerRegistry> availableRegistries,
            Dictionary <string, List <PackageManagerRegistry> > manifestRegistries,
            HashSet <string> selectedRegistryUrls,
            bool addRegistries    = true,
            bool removeRegistries = true,
            bool invertSelection  = false,
            List <PackageManagerRegistry> addedRegistries = null)
        {
            List <PackageManagerRegistry> registriesToAdd;
            List <PackageManagerRegistry> registriesToRemove;
            bool manifestModified = SyncRegistriesToModifier(
                manifestModifier, out registriesToAdd, out registriesToRemove,
                availableRegistries, manifestRegistries, selectedRegistryUrls,
                addRegistries, removeRegistries, invertSelection);

            bool successful = true;

            if (manifestModified)
            {
                successful = manifestModifier.WriteManifest();
                if (successful)
                {
                    if (registriesToAdd.Count > 0)
                    {
                        logger.Log(String.Format(
                                       "Added registries to {0}:\n{1}",
                                       PackageManifestModifier.MANIFEST_FILE_PATH,
                                       PackageManagerRegistry.ToString(registriesToAdd)));
                        if (addedRegistries != null)
                        {
                            addedRegistries.AddRange(registriesToAdd);
                        }
                    }
                    if (registriesToRemove.Count > 0)
                    {
                        logger.Log(String.Format(
                                       "Removed registries from {0}:\n{1}",
                                       PackageManifestModifier.MANIFEST_FILE_PATH,
                                       PackageManagerRegistry.ToString(registriesToRemove)));
                    }
                    analytics.Report(
                        "registry_manifest/write/success",
                        new KeyValuePair <string, string>[] {
                        new KeyValuePair <string, string>("added", registriesToAdd.Count.ToString()),
                        new KeyValuePair <string, string>("removed",
                                                          registriesToRemove.Count.ToString())
                    },
                        "Project Manifest Modified");
                }
                else
                {
                    analytics.Report("registry_manifest/write/failed", "Project Manifest Write Failed");
                }
            }
            return(successful);
        }
        /// <summary>
        /// Remove all scoped registries in the given list.
        /// </summary>
        /// <param name="registries">A list of scoped registry to be removed</param>
        /// <param name="displayWarning">Whether to display a warning if specified registries were not
        /// found.</param>
        /// <returns>true if the registries could be removed, false otherwise.</returns>
        internal bool RemoveRegistries(IEnumerable <PackageManagerRegistry> registries,
                                       bool displayWarning = true)
        {
            List <object> scopedRegistries = null;

            try {
                scopedRegistries = ScopedRegistries;
            } catch (ParseException exception) {
                Logger.Log(String.Format("{0}  Unable to remove registries:\n", exception.ToString(),
                                         PackageManagerRegistry.ToString(registries)),
                           level: LogLevel.Error);
                return(false);
            }
            int removed               = 0;
            int numberOfRegistries    = 0;
            var scopedRegistriesByUrl = PackageManagerRegistries;

            foreach (var registry in registries)
            {
                numberOfRegistries++;
                List <PackageManagerRegistry> existingRegistries;
                if (scopedRegistriesByUrl.TryGetValue(registry.Url, out existingRegistries))
                {
                    int remaining = existingRegistries.Count;
                    foreach (var existingRegistry in existingRegistries)
                    {
                        if (scopedRegistries.Remove(existingRegistry.CustomData))
                        {
                            remaining--;
                        }
                        else
                        {
                            Logger.Log(String.Format("Failed to remove registry '{0}' from '{1}'",
                                                     existingRegistry, MANIFEST_FILE_PATH),
                                       level: LogLevel.Error);
                        }
                    }
                    if (remaining == 0)
                    {
                        removed++;
                    }
                }
            }
            if (displayWarning)
            {
                Logger.Log(String.Format("Removed {0}/{1} registries from '{2}'",
                                         removed, numberOfRegistries, MANIFEST_FILE_PATH),
                           level: removed == numberOfRegistries ? LogLevel.Verbose : LogLevel.Warning);
            }
            return(removed == numberOfRegistries);
        }
Exemple #4
0
        /// <summary>
        /// Read XML declared registries.
        /// </summary>
        /// <param name="filename">File to read.</param>
        /// <param name="logger">Logger class.</param>
        /// <returns>true if the file was read successfully, false otherwise.</returns>
        internal bool Read(string filename, Logger logger)
        {
            PackageManagerRegistry upmRegistry = null;

            logger.Log(String.Format("Reading {0} XML file {1}", UPM_REGISTRIES, filename),
                       level: LogLevel.Verbose);
            if (!XmlUtilities.ParseXmlTextFileElements(
                    filename, logger,
                    (reader, elementName, isStart, parentElementName, elementNameStack) => {
                if (elementName == "registries" && parentElementName == "")
                {
                    return(true);
                }
                else if (elementName == "registry" &&
                         parentElementName == "registries" &&
                         isStart)
                {
                    upmRegistry = new PackageManagerRegistry()
                    {
                        Name = reader.GetAttribute("name") ?? "",
                        Url = reader.GetAttribute("url") ?? "",
                        TermsOfService = reader.GetAttribute("termsOfService") ?? "",
                        PrivacyPolicy = reader.GetAttribute("privacyPolicy") ?? "",
                        CreatedBy = String.Format("{0}:{1}", filename,
                                                  reader.LineNumber)
                    };
                    return(true);
                }
                else if (elementName == "scopes" &&
                         parentElementName == "registry")
                {
                    if (isStart)
                    {
                        upmRegistry.Scopes = new List <string>();
                    }
                    return(true);
                }
                else if (elementName == "scope" &&
                         parentElementName == "scopes" &&
                         !(String.IsNullOrEmpty(upmRegistry.Name) ||
                           String.IsNullOrEmpty(upmRegistry.Url)))
                {
                    if (isStart && reader.Read() && reader.NodeType == XmlNodeType.Text)
                    {
                        upmRegistry.Scopes.Add(reader.ReadContentAsString());
                    }
                    return(true);
                }
                else if (elementName == "registry" &&
                         parentElementName == "registries" &&
                         !isStart)
                {
                    if (!(String.IsNullOrEmpty(upmRegistry.Name) ||
                          String.IsNullOrEmpty(upmRegistry.Url) ||
                          upmRegistry.Scopes.Count == 0))
                    {
                        PackageManagerRegistry existingRegistry;
                        if (!Registries.TryGetValue(upmRegistry.Url, out existingRegistry))
                        {
                            Registries[upmRegistry.Url] = upmRegistry;
                        }
                        else if (!existingRegistry.Equals(upmRegistry))
                        {
                            logger.Log(
                                String.Format(
                                    "{0} for URL '{1}' called '{2}' was already read " +
                                    "from '{3}'.\n" +
                                    "{0} from '{4}' will be ignored.",
                                    UPM_REGISTRIES, upmRegistry.Url, upmRegistry.Name,
                                    existingRegistry.CreatedBy, filename),
                                level: LogLevel.Warning);
                        }
                    }
                    else
                    {
                        logger.Log(
                            String.Format(
                                "Malformed {0} for registry {1} " +
                                "found in {2}.\n" +
                                "All {0} will be ignored in {2}.",
                                UPM_REGISTRIES, upmRegistry.ToString(), filename),
                            level: LogLevel.Error);
                        return(false);
                    }
                    return(true);
                }
                return(false);
            }))
            {
                return(false);
            }
            return(true);
        }
        /// <summary>
        /// Apply registry changes to the projects manifest.
        /// </summary>
        /// <param name="manifestModifier">Object that modifies the project's manifest.</param>
        /// <param name="availableRegistries">Registries that are available in the
        /// configuration.</param>
        /// <param name="manifestRegistries">Registries that are present in the manifest.</param>
        /// <param name="selectedRegistryUrls">URLs of selected registries, these should be items in
        /// availableRegistries.</param>
        /// <param name="addRegistries">Whether to add selected registries to the manifest.</param>
        /// <param name="removeRegistries">Whether to remove unselected registries from the
        /// manifest.</param>
        /// <param name="invertSelection">If false, adds the selected registries and removes the
        /// unselected registries.  If true, removes the selected registries and adds the unselected
        /// registries.</param>
        /// <param name="addedRegistries">If specified, is extended with the list of registries added
        /// to the manifest.<param>
        /// <returns>true if successful, false otherwise.</returns>
        private static bool SyncRegistriesToManifest(
            PackageManifestModifier manifestModifier,
            Dictionary <string, PackageManagerRegistry> availableRegistries,
            Dictionary <string, List <PackageManagerRegistry> > manifestRegistries,
            HashSet <string> selectedRegistryUrls,
            bool addRegistries    = true,
            bool removeRegistries = true,
            bool invertSelection  = false,
            List <PackageManagerRegistry> addedRegistries = null)
        {
            // Build a list of registries to add to and remove from the manifest.
            var registriesToAdd    = new List <PackageManagerRegistry>();
            var registriesToRemove = new List <PackageManagerRegistry>();

            foreach (var availableRegistry in availableRegistries.Values)
            {
                var  url        = availableRegistry.Url;
                bool isSelected = selectedRegistryUrls.Contains(url);
                if (invertSelection)
                {
                    isSelected = !isSelected;
                }

                bool currentlyInManifest = manifestRegistries.ContainsKey(url);

                if (isSelected)
                {
                    if (addRegistries && !currentlyInManifest)
                    {
                        registriesToAdd.Add(availableRegistry);
                    }
                }
                else
                {
                    if (removeRegistries && currentlyInManifest)
                    {
                        registriesToRemove.Add(availableRegistry);
                    }
                }
            }

            bool manifestModified = false;

            if (registriesToAdd.Count > 0)
            {
                manifestModifier.AddRegistries(registriesToAdd);
                manifestModified = true;
            }
            if (registriesToRemove.Count > 0)
            {
                manifestModifier.RemoveRegistries(registriesToRemove);
                manifestModified = true;
            }

            bool successful = true;

            if (manifestModified)
            {
                successful = manifestModifier.WriteManifest();
                if (successful)
                {
                    if (registriesToAdd.Count > 0)
                    {
                        logger.Log(String.Format(
                                       "Added registries to {0}:\n{1}",
                                       PackageManifestModifier.MANIFEST_FILE_PATH,
                                       PackageManagerRegistry.ToString(registriesToAdd)));
                        if (addedRegistries != null)
                        {
                            addedRegistries.AddRange(registriesToAdd);
                        }
                    }
                    if (registriesToRemove.Count > 0)
                    {
                        logger.Log(String.Format(
                                       "Removed registries from {0}:\n{1}",
                                       PackageManifestModifier.MANIFEST_FILE_PATH,
                                       PackageManagerRegistry.ToString(registriesToRemove)));
                    }
                    analytics.Report(
                        "registry_manifest/write/success",
                        new KeyValuePair <string, string>[] {
                        new KeyValuePair <string, string>("added", registriesToAdd.Count.ToString()),
                        new KeyValuePair <string, string>("removed",
                                                          registriesToRemove.Count.ToString())
                    },
                        "Project Manifest Modified");
                }
                else
                {
                    analytics.Report("registry_manifest/write/failed", "Project Manifest Write Failed");
                }
            }
            return(successful);
        }