Exemple #1
0
        public static PackageMetadataProvider FromPackage(ManifestFolder package)
        {
            var doc      = package.Read(out var title);
            var metadata = new PackageMetadataProvider()
            {
                Title = title
            };

            metadata.AddRange(doc.SelectNodes("/AML/AML/Item")
                              .OfType <System.Xml.XmlElement>()
                              .Select(e => ElementFactory.Local.FromXml(e).AssertItem()));
            return(metadata);
        }
Exemple #2
0
        public static PackageMetadataProvider FromScript(InstallScript script)
        {
            var metadata = new PackageMetadataProvider()
            {
                Title = script.Title
            };

            metadata.AddRange(script.Lines
                              .Where(l => l.Type != InstallType.DependencyCheck &&
                                     l.Type != InstallType.Warning)
                              .Select(l => ElementFactory.Local.FromXml(l.Script).AssertItem()));
            return(metadata);
        }
        public static PackageMetadataProvider WriteAmlMergeScripts(this IDiffDirectory baseDir, IDiffDirectory compareDir
                                                                   , Func <string, int, XmlWriter> callback = null)
        {
            Func <IDiffFile, IComparable> keyGetter = i => i.Path.Replace('\\', '/').TrimStart('/');
            var basePaths    = baseDir.GetFiles().OrderBy(keyGetter).ToArray();
            var comparePaths = compareDir.GetFiles().OrderBy(keyGetter).ToArray();
            var completed    = 0;
            var total        = basePaths.Length + comparePaths.Length;
            var result       = new List <FileDiff>();
            var metadata     = new PackageMetadataProvider();

            basePaths.MergeSorted(comparePaths, keyGetter, (i, b, c) =>
            {
                try
                {
                    var path = (c ?? b).Path;
                    if (path.EndsWith(".xslt.xml") || path.EndsWith(".innpkg"))
                    {
                        return;
                    }

                    completed++;
                    switch (i)
                    {
                    case -1: // Delete
                        using (var baseStream = ReadFile(b, p => Array.Find(basePaths, f => f.Path == p)))
                            using (var writer = callback(path, completed * 100 / total))
                            {
                                var elem = AmlDiff.GetMergeScript(baseStream, null);
                                if (elem.Elements().Any())
                                {
                                    elem.WriteTo(writer);
                                }
                            }
                        break;

                    case 1: // Add
                        using (var baseStream = ReadFile(c, p => Array.Find(comparePaths, f => f.Path == p)))
                        {
                            var elem = XElement.Load(baseStream);
                            IdentityMergeToAdd(elem);
                            if (ItemAddToIgnore(elem))
                            {
                                return;
                            }

                            using (var writer = callback(path, completed * 100 / total))
                            {
                                elem.WriteTo(writer);
                                metadata.Add(elem);
                            }
                        }
                        break;

                    default: // Edit
                        total--;
                        using (var baseStream = ReadFile(b, p => Array.Find(basePaths, f => f.Path == p)))
                            using (var compareStream = ReadFile(c, p => Array.Find(comparePaths, f => f.Path == p)))
                                using (var writer = callback(path, completed * 100 / total))
                                {
                                    var baseElem    = Utils.LoadXml(baseStream);
                                    var compareElem = Utils.LoadXml(compareStream);
                                    metadata.Add(compareElem);
                                    var elem = AmlDiff.GetMergeScript(baseElem, compareElem);
                                    if (elem.Elements().Any())
                                    {
                                        elem.WriteTo(writer);
                                    }
                                }
                        break;
                    }
                }
                catch (XmlException ex)
                {
                    ex.Data["Index"] = i;
                    if (b != null)
                    {
                        ex.Data["BasePath"] = b.Path;
                    }
                    if (c != null)
                    {
                        ex.Data["ComparePath"] = c.Path;
                    }
                    throw;
                }
            });

            return(metadata);
        }
        private IEnumerable <InstallItem> FillInNullsOnRequiredProperties(XmlElement[] allItems, PackageMetadataProvider metadata)
        {
            var newlyRequiredProps = allItems.Where(i => i.Attribute("type") == "Property" &&
                                                    i.Attribute("action") == "edit" &&
                                                    !string.IsNullOrEmpty(i.Attribute("id")) &&
                                                    i.Element("is_required", "0") == "1" &&
                                                    i.Element("default_value").HasValue())
                                     .ToArray();

            if (newlyRequiredProps.Length > 0)
            {
                var doc  = newlyRequiredProps[0].NewDoc();
                var root = doc.Elem("AML");
                var idx  = 0;

                foreach (var prop in newlyRequiredProps)
                {
                    string name;
                    metadata.PropById(prop.Attribute("id"), out name);
                    var typeId   = prop.Parent().Parent().Attribute("id");
                    var typeName = metadata.ItemTypes.Single(i => i.Id == typeId).Name;
                    var script   = root.Elem("Item").Attr("type", typeName).Attr("action", "edit").Attr("where", "[" + typeName + "]." + name + " is null");
                    script.Elem(name, prop.Element("default_value", ""));
                    yield return(InstallItem.FromScript(script, "_Scripts/NewlyRequiredProp (" + (++idx) + ").xml"));
                }
            }
        }
Exemple #5
0
        public static PackageMetadataProvider WriteAmlMergeScripts(this IDiffDirectory baseDir, IDiffDirectory compareDir
                                                                   , Func <string, int, XmlWriter> callback = null)
        {
            Func <IDiffFile, IComparable> keyGetter = i => i.Path;
            var basePaths    = baseDir.GetFiles().OrderBy(keyGetter).ToArray();
            var comparePaths = compareDir.GetFiles().OrderBy(keyGetter).ToArray();
            var completed    = 0;
            var total        = basePaths.Length + comparePaths.Length;
            var result       = new List <FileDiff>();
            var metadata     = new PackageMetadataProvider();

            basePaths.MergeSorted(comparePaths, keyGetter, (i, b, c) =>
            {
                try
                {
                    var path = (c ?? b).Path;
                    if (path.EndsWith(".xslt.xml") || path.EndsWith(".innpkg"))
                    {
                        return;
                    }

                    completed++;
                    switch (i)
                    {
                    case -1: // Delete
                        using (var baseStream = ReadFile(b, p => Array.Find(basePaths, f => f.Path == p)))
                            using (var writer = callback(path, completed * 100 / total))
                            {
                                var elem = AmlDiff.GetMergeScript(baseStream, null);
                                if (elem.Elements().Any())
                                {
                                    elem.WriteTo(writer);
                                }
                            }
                        break;

                    case 1: // Add
                        using (var baseStream = c.OpenRead())
                            using (var writer = callback(path, completed * 100 / total))
                            {
                                var elem = XElement.Load(baseStream);
                                elem.WriteTo(writer);
                                metadata.Add(elem);
                            }
                        break;

                    default: // Edit
                        total--;
                        using (var baseStream = ReadFile(b, p => Array.Find(basePaths, f => f.Path == p)))
                            using (var compareStream = ReadFile(c, p => Array.Find(comparePaths, f => f.Path == p)))
                                using (var writer = callback(path, completed * 100 / total))
                                {
                                    var baseElem    = Utils.LoadXml(baseStream);
                                    var compareElem = Utils.LoadXml(compareStream);
                                    metadata.Add(compareElem);
                                    var elem = AmlDiff.GetMergeScript(baseElem, compareElem);
                                    if (elem.Elements().Any())
                                    {
                                        elem.WriteTo(writer);
                                    }
                                }
                        break;
                    }
                }
                catch (XmlException ex)
                {
                    throw new XmlException(string.Format("{0} ({1}, {2}, {3})", ex.Message, i, b.Path, c.Path), ex);
                }
            });

            return(metadata);
        }
Exemple #6
0
        /// <summary>
        /// Writes the difference between two directories
        /// </summary>
        /// <param name="baseDir">The base directory which needs to be transformed</param>
        /// <param name="compareDir">The comparison directory which is what the base directoy should look like after transformation</param>
        /// <param name="callback">Gets an XML writer to write the merge script given the path and current progress (integer between 0 and 100)</param>
        /// <returns>Metadata regarding the target state</returns>
        public static PackageMetadataProvider WriteAmlMergeScripts(this IPackage baseDir, IPackage compareDir
                                                                   , Func <string, int, XmlWriter> callback)
        {
            Func <IPackageFile, IComparable> keyGetter = i => i.Path.ToUpperInvariant().Replace('\\', '/').TrimStart('/');
            var basePaths    = baseDir.Files().OrderBy(keyGetter).ToList();
            var comparePaths = compareDir.Files().OrderBy(keyGetter).ToList();
            var completed    = 0;
            var total        = basePaths.Count + comparePaths.Count;
            var metadata     = new PackageMetadataProvider();

            var baseScripts    = new List <AmlScript>();
            var compareScripts = new List <AmlScript>();

            Action <MergeType, AmlScript, AmlScript> mergeScripts = (type, baseScript, compareScript) =>
            {
                switch (type)
                {
                case MergeType.StartOnly: // Delete
                    completed++;
                    using (var writer = callback(baseScript.Path, completed * 100 / total))
                    {
                        var elem = AmlDiff.GetMergeScript(baseScript.Script, null);
                        if (elem.Elements().Any())
                        {
                            elem.WriteTo(writer);
                        }
                    }
                    break;

                case MergeType.DestinationOnly: // Add
                    completed++;
                    using (var writer = callback(compareScript.Path, completed * 100 / total))
                    {
                        compareScript.Script.WriteTo(writer);
                        metadata.Add(compareScript.Script);
                    }
                    break;

                default:
                    total--;
                    completed++;

                    var path = compareScript.Path;
                    if (!string.Equals(baseScript.Path, compareScript.Path, StringComparison.OrdinalIgnoreCase) &&
                        !string.IsNullOrEmpty(compareScript.Id) &&
                        baseScript.Path.IndexOf(compareScript.Id) >= 0)
                    {
                        path = baseScript.Path;
                    }
                    using (var writer = callback(path, completed * 100 / total))
                    {
                        metadata.Add(compareScript.Script);
                        var elem = AmlDiff.GetMergeScript(baseScript.Script, compareScript.Script);
                        if (elem.Elements().Any())
                        {
                            elem.WriteTo(writer);
                        }
                    }
                    break;
                }
            };

            basePaths.MergeSorted(comparePaths, keyGetter, (type, baseFile, compareFile) =>
            {
                try
                {
                    var path = (compareFile ?? baseFile).Path;
                    if (path.EndsWith(".xslt.xml", StringComparison.OrdinalIgnoreCase) ||
                        path.EndsWith(".innpkg", StringComparison.OrdinalIgnoreCase))
                    {
                        return;
                    }

                    switch (type)
                    {
                    case MergeType.StartOnly: // Delete
                        var baseScript = new AmlScript(baseFile, baseDir);
                        if (baseScript.Key == null)
                        {
                            mergeScripts(type, baseScript, null);
                        }
                        else
                        {
                            baseScripts.Add(baseScript);
                        }
                        break;

                    case MergeType.DestinationOnly: // Add
                        var compareScript = new AmlScript(compareFile, compareDir);
                        IdentityMergeToAdd(compareScript.Script);
                        if (ItemAddToIgnore(compareScript.Script))
                        {
                            return;
                        }

                        if (compareScript.Key == null)
                        {
                            mergeScripts(type, null, compareScript);
                        }
                        else
                        {
                            compareScripts.Add(compareScript);
                        }
                        break;

                    default: // Edit
                        baseScript    = new AmlScript(baseFile, baseDir);
                        compareScript = new AmlScript(compareFile, compareDir);
                        if (baseScript.Key == compareScript.Key)
                        {
                            mergeScripts(type, baseScript, compareScript);
                        }
                        else
                        {
                            baseScripts.Add(baseScript);
                            compareScripts.Add(compareScript);
                        }
                        break;
                    }
                }
                catch (XmlException ex)
                {
                    ex.Data["MergeType"] = type.ToString();
                    if (baseFile != null)
                    {
                        ex.Data["BasePath"] = baseFile.Path;
                    }
                    if (compareFile != null)
                    {
                        ex.Data["ComparePath"] = compareFile.Path;
                    }
                    throw;
                }
            });

            baseScripts    = baseScripts.OrderBy(s => s.Key).ToList();
            compareScripts = compareScripts.OrderBy(s => s.Key).ToList();

            baseScripts.MergeSorted(compareScripts, s => s.Key, mergeScripts);
            return(metadata);
        }