コード例 #1
0
        protected AssemblyDetail ExtractAll(string assemblyFile, DiffConfig config)
        {
            string cacheKey = assemblyFile + "|" + config.ToString();

            if (config.IsolationLevel == AppDomainIsolationLevel.AutoDetect)
            {
                config.IsolationLevel = AppDomainIsolationLevel.Medium;
            }

            if (!_infCache.ContainsKey(cacheKey))
            {
                lock (typeof(TestBase))
                {
                    if (!_infCache.ContainsKey(cacheKey))
                    {
                        if (!File.Exists(assemblyFile))
                        {
                            Assert.Inconclusive("Unable to locate subject assembly");
                        }

                        AssemblyManager am  = AssemblyManagerFactory.Create(config.IsolationLevel);
                        AssemblyDetail  inf = am.ExtractAssemblyInf(assemblyFile, config);

                        _infCache.Add(cacheKey, inf);
                    }
                }
            }

            return((AssemblyDetail)_infCache[cacheKey].Clone());
        }
コード例 #2
0
 public DiffingHashComparer(DiffConfig diffConfig = null)
 {
     if (diffConfig != null)
     {
         DiffConfig = diffConfig;
     }
 }
コード例 #3
0
ファイル: EndToEnd.cs プロジェクト: harold4/bitdiffer
        private static List <AssemblyDetail> DoCompare(DiffConfig config)
        {
            AssemblyComparison ac = new AssemblyComparer().CompareAssemblyFiles(config, ComparisonFilter.Default, Subjects.One, Subjects.Two);

            Assert.AreEqual(1, ac.Groups.Count);
            return(ac.Groups[0].Assemblies);
        }
コード例 #4
0
ファイル: Delta.cs プロジェクト: theThorsager/BHoM_Engine
        public static Delta Delta(List <IBHoMObject> objects, object streamId, string revisionName = null,
                                  string comment = null, DiffConfig diffConfig = null)
        {
            Revision revision = Create.Revision(objects, streamId, revisionName, comment, diffConfig);

            return(Delta(revision, diffConfig, comment));
        }
コード例 #5
0
        public AssemblyComparison CompareAssemblyFiles(DiffConfig config, ComparisonFilter filter, params string[] assemblyFiles)
        {
            _config = config;
            _filter = filter;

            if (_progress != null)
            {
                _progress.SetMaxRange(assemblyFiles.Length);
            }

            if (assemblyFiles.Length == 0)
            {
                return(null);
            }

            AppDomainIsolationLevel level = _config.IsolationLevel;

            if (level == AppDomainIsolationLevel.AutoDetect)
            {
                level = IsolationDetector.AutoDetectIsolationLevelFiles(assemblyFiles);
            }

            AssemblyManager    manager = AssemblyManagerFactory.Create(level);
            AssemblyComparison ac      = new AssemblyComparison();

            ac.Groups.Add(DoCompareFiles(manager, assemblyFiles));

            manager.AllExtractionsComplete();

            FilterResultSet(ac, filter);

            return(ac);
        }
コード例 #6
0
        public static Diff DiffGenericObjects(IEnumerable <object> pastObjects, IEnumerable <object> currentObjects, DiffConfig diffConfig = null, bool useExistingHash = false)
        {
            BH.Engine.Reflection.Compute.RecordNote("This diffing method cannot track modified objects between different revisions." +
                                                    "\nIt will simply return the objects that appear exclusively in the past set, in the following set, and in both." +
                                                    $"\nConsider using '{nameof(DiffWithCustomId)}', '{nameof(DiffWithFragmentId)}' or '{nameof(DiffRevisions)}' if this feature is needed.");

            // Set configurations if diffConfig is null. Clone it for immutability in the UI.
            DiffConfig diffConfigCopy = diffConfig == null ? new DiffConfig() : (DiffConfig)diffConfig.DeepClone();

            // Clone objects for immutability in the UI.
            List <object> pastObjects_cloned    = BH.Engine.Base.Query.DeepClone(pastObjects).ToList();
            List <object> currentObjects_cloned = BH.Engine.Base.Query.DeepClone(currentObjects).ToList();

            if (!useExistingHash)
            {
                // Clean any existing hash fragment.
                // This ensures the hash will be re-computed within this method using the provided DiffConfig.
                pastObjects_cloned.OfType <IBHoMObject>().ToList().ForEach(o => o.Fragments.Remove(typeof(HashFragment)));
                currentObjects_cloned.OfType <IBHoMObject>().ToList().ForEach(o => o.Fragments.Remove(typeof(HashFragment)));
            }

            // Compute the "Diffing" by means of a VennDiagram.
            // Hashes are computed in the DiffingHashComparer, once per each object (the hash is stored in a hashFragment).
            VennDiagram <object> vd = Engine.Data.Create.VennDiagram(pastObjects_cloned, currentObjects_cloned, new DiffingHashComparer <object>(diffConfigCopy, true));

            return(new Diff(vd.OnlySet2, vd.OnlySet1, null, diffConfigCopy, null, vd.Intersection));
        }
コード例 #7
0
        public static string DiffingHash(this object obj, DiffConfig diffConfig = null)
        {
            diffConfig = diffConfig == null ? new DiffConfig() : (DiffConfig)diffConfig.DeepClone();

            // The following is to consider only the PropertiesToInclude specified in the diffConfig.
            // Since the SHA hash algorithm can only consider "exceptions", we need to retrieve all the top level properties,
            // intersect them with the set of PropertiesToInclude, and treat all the properties that remain out as "exceptions" (not to be considered).
            if (diffConfig.PropertiesToConsider.Any())
            {
                IEnumerable <string> exceptions = BH.Engine.Reflection.Query.PropertyNames(obj).Except(diffConfig.PropertiesToConsider);
                diffConfig.PropertiesToIgnore.AddRange(exceptions);
            }

            // The current Hash must not be considered when computing the hash. Remove HashFragment if present.
            IBHoMObject bhomobj = obj as IBHoMObject;

            if (bhomobj != null)
            {
                bhomobj = BH.Engine.Base.Query.DeepClone(obj) as IBHoMObject;
                bhomobj.Fragments.Remove(typeof(HashFragment));
                return(Compute.SHA256Hash(bhomobj, diffConfig.PropertiesToIgnore));
            }

            return(Compute.SHA256Hash(obj, diffConfig.PropertiesToIgnore));
        }
コード例 #8
0
ファイル: Configuration.cs プロジェクト: harold4/bitdiffer
 internal void SaveOptions(DiffConfig diffConfig)
 {
     diffConfig.IsolationLevel           = (cbIsolationLevel.SelectedIndex == 2) ? AppDomainIsolationLevel.Medium : ((cbIsolationLevel.SelectedIndex == 1) ? AppDomainIsolationLevel.High : AppDomainIsolationLevel.AutoDetect);
     diffConfig.TryResolveGACFirst       = cbResolvePref.SelectedIndex == 1;
     diffConfig.UseReflectionOnlyContext = cbContext.SelectedIndex == 0;
     diffConfig.Multithread = cbThreading.SelectedIndex == 0;
 }
コード例 #9
0
ファイル: Configuration.cs プロジェクト: harold4/bitdiffer
 internal void LoadOptions(DiffConfig diffConfig)
 {
     cbIsolationLevel.SelectedIndex = (diffConfig.IsolationLevel == AppDomainIsolationLevel.Medium) ? 2 : ((diffConfig.IsolationLevel == AppDomainIsolationLevel.High) ? 1 : 0);
     cbResolvePref.SelectedIndex    = diffConfig.TryResolveGACFirst ? 1 : 0;
     cbContext.SelectedIndex        = diffConfig.UseReflectionOnlyContext ? 0 : 1;
     cbThreading.SelectedIndex      = diffConfig.Multithread ? 0 : 1;
 }
コード例 #10
0
        public void AppDomain_Isolation_High_ReflOnly()
        {
            DiffConfig config = new DiffConfig();

            config.IsolationLevel           = AppDomainIsolationLevel.High;
            config.UseReflectionOnlyContext = true;
            ExtractAll(Subjects.One, config);
            AssertAssemblyNotInCurrentAppDomain("BitDiffer.Tests.Subject");
        }
コード例 #11
0
        private void AssertChange(string from, string name, ChangeType change, DiffConfig config)
        {
            PropertyDetail r1 = ExtractProperty(Subjects.One, from, name, config);
            PropertyDetail r2 = ExtractProperty(Subjects.Two, from, name, config);

            Align(r1, r2);

            Assert.AreEqual(change, r2.PerformCompare(r1));
        }
コード例 #12
0
        protected T ExtractItem <T>(string assemblyFile, string name, DiffConfig config) where T : ICanAlign, new()
        {
            AssemblyDetail all = ExtractAll(assemblyFile, config);

            T t = ListOperations.FindOrReturnMissing(all.FilterChildren <T>(), name);

            Log.Verbose("Extracted Item {0} : {1}", t.GetType().Name, t.ToString());
            return(t);
        }
コード例 #13
0
 internal void LoadOptions(DiffConfig config)
 {
     if (string.IsNullOrEmpty(config.ReferenceDirectories))
     {
         gridFolders.Items = new List <string>();
     }
     else
     {
         gridFolders.Items = new List <string>(config.ReferenceDirectories.Split(';'));
     }
 }
コード例 #14
0
        public static Diff DiffOneByOne(IEnumerable <object> pastObjects, IEnumerable <object> currentObjects, DiffConfig diffConfig = null, bool useExistingHash = false)
        {
            if (pastObjects.Count() != currentObjects.Count())
            {
                BH.Engine.Reflection.Compute.RecordWarning($"Input collections must be of the same length for '{nameof(DiffOneByOne)}' to work.");
                return(null);
            }

            BH.Engine.Reflection.Compute.RecordNote($"This diffing method is equivalent to Equivalent to calling '{nameof(Query.DifferentProperties)}' on the input lists. " +
                                                    $"\nThis will only identify 'modified' or 'unchanged' objects. For 'modified' objects, the property differences are also returned." +
                                                    $"\nIt will work correctly only if the objects in the lists are in the same order and at most they have been modified (i.e. no new object has been added, no object has been deleted).");

            // Set configurations if diffConfig is null. Clone it for immutability in the UI.
            DiffConfig diffConfigCopy = diffConfig == null ? new DiffConfig() : (DiffConfig)diffConfig.DeepClone();

            diffConfigCopy.EnablePropertyDiffing = true; // must be forced on for this Diffing method to make sense.

            // Clone objects for immutability in the UI.
            List <object> pastObjects_cloned    = BH.Engine.Base.Query.DeepClone(pastObjects).ToList();
            List <object> currentObjects_cloned = BH.Engine.Base.Query.DeepClone(currentObjects).ToList();

            List <object> modifiedObjects  = new List <object>();
            List <object> unchangedObjects = new List <object>();

            bool anyChangeDetected = false;

            var allModifiedProps = new Dictionary <string, Dictionary <string, Tuple <object, object> > >();

            for (int i = 0; i < pastObjects_cloned.Count(); i++)
            {
                var modifiedProps = Query.DifferentProperties(currentObjects_cloned[i], pastObjects_cloned[i], diffConfigCopy);

                if (modifiedProps != null && modifiedProps.Any())
                {
                    modifiedObjects.Add(currentObjects_cloned[i]);
                    anyChangeDetected = true;
                }
                else if (diffConfig.StoreUnchangedObjects)
                {
                    unchangedObjects.Add(currentObjects_cloned[i]);
                }

                allModifiedProps[$"Object #{i}"] = modifiedProps ?? new Dictionary <string, Tuple <object, object> >();
            }

            if (!anyChangeDetected)
            {
                allModifiedProps = null;
            }

            return(new Diff(new List <object>(), new List <object>(), modifiedObjects, diffConfigCopy, allModifiedProps, unchangedObjects));
        }
コード例 #15
0
        public static void SetHashFragment(IEnumerable <IBHoMObject> objs, DiffConfig diffConfig = null)
        {
            // Set configurations if diffConfig is null
            diffConfig = diffConfig == null ? new DiffConfig() : diffConfig;

            // Calculate and set the object hashes
            foreach (var obj in objs)
            {
                string hash = BH.Engine.Diffing.Compute.DiffingHash(obj, diffConfig);

                HashFragment existingFragm = obj.GetHashFragment();

                obj.Fragments.AddOrReplace(new HashFragment(hash, existingFragm?.Hash));
            }
        }
コード例 #16
0
        public AssemblyDetail ExtractAssemblyInf(string assemblyPath, DiffConfig config)
        {
            if (!Path.IsPathRooted(assemblyPath))
            {
                assemblyPath = Path.GetFullPath(assemblyPath);
            }

            Log.Verbose("Extracting from assembly {0}", Path.GetFileName(assemblyPath));

            DomainExtractorPair pair = GetExtractor(assemblyPath);
            AssemblyDetail      ad   = pair.Extractor.ExtractFrom(assemblyPath, config);

            OneExtractionComplete(pair);
            return(ad);
        }
コード例 #17
0
        public static List <T> SetHashFragment <T>(this IEnumerable <T> objs, DiffConfig diffConfig = null) where T : IBHoMObject
        {
            // Clone the current objects to preserve immutability
            List <T> objs_cloned = new List <T>();

            // Set configurations if diffConfig is null
            diffConfig = diffConfig == null ? new DiffConfig() : diffConfig;

            // Calculate and set the object hashes
            foreach (var obj in objs)
            {
                objs_cloned.Add(SetHashFragment(obj, diffConfig));
            }

            return(objs_cloned);
        }
コード例 #18
0
        public static bool HasMergeablePropertiesWith(Space element, Space other)
        {
            DiffConfig config = new DiffConfig()
            {
                PropertiesToIgnore = new List <string>
                {
                    "Location",
                    "Type",
                    "BHoM_Guid",
                    "CustomData",
                },
                NumericTolerance = BH.oM.Geometry.Tolerance.Distance,
            };

            return(Diffing.Query.DifferentProperties(element, other, config) == null);
        }
コード例 #19
0
        public static T SetHashFragment <T>(T obj, DiffConfig diffConfig = null) where T : IBHoMObject
        {
            // Clone the current object to preserve immutability
            T obj_cloned = BH.Engine.Base.Query.DeepClone(obj);

            // Set configurations if diffConfig is null
            diffConfig = diffConfig == null ? new DiffConfig() : diffConfig;

            // Calculate and set the object hashes
            string hash = BH.Engine.Diffing.Compute.DiffingHash(obj_cloned, diffConfig);

            HashFragment existingFragm = obj_cloned.GetHashFragment();

            obj_cloned.Fragments.AddOrReplace(new HashFragment(hash, existingFragm?.CurrentHash));

            return(obj_cloned);
        }
コード例 #20
0
ファイル: AssemblyManager.cs プロジェクト: harold4/bitdiffer
        public AssemblyDetail ExtractAssemblyInf(string assemblyPath, DiffConfig config)
        {
            if (!Path.IsPathRooted(assemblyPath))
            {
                assemblyPath = Path.GetFullPath(assemblyPath);
            }

            Log.Verbose("Extracting from assembly {0}", Path.GetFileName(assemblyPath));

            var deleteFiles          = new ConcurrentQueue <string>();
            DomainExtractorPair pair = GetExtractor(assemblyPath);
            AssemblyDetail      ad   = pair.Extractor.ExtractFrom(assemblyPath, config, ref deleteFiles);

            OneExtractionComplete(pair);
            OnUnloadDeleteFiles(deleteFiles);
            return(ad);
        }
コード例 #21
0
        public static bool HasMergeablePropertiesWith(Opening element, Opening other)
        {
            DiffConfig config = new DiffConfig()
            {
                PropertiesToIgnore = new List <string>
                {
                    "Edges",
                    "FrameFactorValue",
                    "InnerEdges",
                    "Type",
                    "BHoM_Guid",
                    "CustomData",
                },
                NumericTolerance = BH.oM.Geometry.Tolerance.Distance,
            };

            return(Diffing.Query.DifferentProperties(element, other, config) == null);
        }
コード例 #22
0
        public static bool HasMergeablePropertiesWith(Panel element, Panel other)
        {
            DiffConfig config = new DiffConfig()
            {
                PropertiesToIgnore = new List <string>
                {
                    "ExternalEdges",
                    "Openings",
                    "ConnectedSpaces",
                    "Type",
                    "BHoM_Guid",
                    "CustomData",
                },
                NumericTolerance = BH.oM.Geometry.Tolerance.Distance,
            };

            return(Diffing.Query.DifferentProperties(element, other, config) == null);
        }
コード例 #23
0
        // Computes the diffing for IEnumerable<object>.
        // For BHoMObjects, it assumes that they all have a HashFragment assigned (like when they have been passed through a Revision).
        // For non-BHoMObjects, it performs the VennDiagram comparision with a HashComparer.
        // Results for BHoMObjects and non are concatenated.
        private static Diff DiffRevisionObjects(IEnumerable <object> pastRevisionObjs, IEnumerable <object> followingRevisionObjs, DiffConfig diffConfig = null)
        {
            // Set configurations if diffConfig is null. Clone it for immutability in the UI.
            DiffConfig diffConfigCopy = diffConfig == null ? new DiffConfig() : diffConfig.DeepClone() as DiffConfig;

            // Dispatch the objects in BHoMObjects and generic objects.
            IEnumerable <IBHoMObject> prevObjs_BHoM = pastRevisionObjs.OfType <IBHoMObject>();
            IEnumerable <IBHoMObject> currObjs_BHoM = followingRevisionObjs.OfType <IBHoMObject>();

            // If all objects are bhomobjects, just call the appropriate method
            if (pastRevisionObjs.Count() != 0 && pastRevisionObjs.Count() == prevObjs_BHoM.Count() && followingRevisionObjs.Count() == currObjs_BHoM.Count())
            {
                return(DiffRevisionObjects(prevObjs_BHoM, currObjs_BHoM, diffConfigCopy));
            }

            IEnumerable <object> prevObjs_nonBHoM = pastRevisionObjs.Where(o => !(o is IBHoMObject));
            IEnumerable <object> currObjs_nonBHoM = followingRevisionObjs.Where(o => !(o is IBHoMObject));

            // Compute the specific Diffing for the BHoMObjects.
            Diff diff = Compute.DiffRevisionObjects(prevObjs_BHoM, currObjs_BHoM, diffConfigCopy);

            // Compute the generic Diffing for the other objects.
            // This is left to the VennDiagram with a HashComparer.
            VennDiagram <object> vd = Engine.Data.Create.VennDiagram(prevObjs_nonBHoM, currObjs_nonBHoM, new DiffingHashComparer <object>(diffConfig));

            // Concatenate the results of the two diffing operations.
            List <object> allPrevObjs      = new List <object>();
            List <object> allCurrObjs      = new List <object>();
            List <object> allUnchangedObjs = new List <object>();

            allCurrObjs.AddRange(diff.AddedObjects);
            allCurrObjs.AddRange(vd.OnlySet1);

            allPrevObjs.AddRange(diff.RemovedObjects);
            allPrevObjs.AddRange(vd.OnlySet2);

            // Create the final, actual diff.
            Diff finalDiff = new Diff(allCurrObjs, allPrevObjs, diff.ModifiedObjects, diffConfigCopy, diff.ModifiedPropsPerObject, diff.UnchangedObjects);

            return(finalDiff);
        }
コード例 #24
0
        public AssemblyDetail ExtractFrom(string assemblyFile, DiffConfig config, ref ConcurrentQueue <string> deleteFileList)
        {
            Assembly assembly;

            _assemblyFile = assemblyFile;
            _config       = config;

            // Handle standard and .winmd resolve events
            AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += CurrentDomain_ReflectionOnlyAssemblyResolve;
            WindowsRuntimeMetadata.ReflectionOnlyNamespaceResolve += WindowsRuntimeMetadata_ReflectionOnlyNamespaceResolve;

            try
            {
                if (config.UseReflectionOnlyContext)
                {
                    Log.Info("Loading assembly {0} (ReflectionContext)", assemblyFile);
                    assembly = Assembly.ReflectionOnlyLoadFrom(assemblyFile);
                }
                else
                {
                    Log.Info("Loading assembly {0}", assemblyFile);
                    assembly = Assembly.LoadFrom(assemblyFile);
                }
                var loader = new AssemblyLoader(assembly, deleteFileList);
                loader.CreateDlls(Path.GetDirectoryName(Path.GetFullPath(assemblyFile)));
                return(new AssemblyDetail(assembly));
            }
            catch (Exception ex)
            {
                var errMessage = ex.GetNestedExceptionMessage();
                Log.Error(errMessage);
                throw new Exception(errMessage);
            }
            finally
            {
                AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve -= CurrentDomain_ReflectionOnlyAssemblyResolve;
                WindowsRuntimeMetadata.ReflectionOnlyNamespaceResolve -= WindowsRuntimeMetadata_ReflectionOnlyNamespaceResolve;
            }
        }
コード例 #25
0
        public static Diff DiffWithFragmentId(IEnumerable <IBHoMObject> pastObjects, IEnumerable <IBHoMObject> currentObjects, Type fragmentType, string fragmentIdProperty, DiffConfig diffConfig = null)
        {
            // Set configurations if diffConfig is null. Clone it for immutability in the UI.
            DiffConfig diffConfigCopy = diffConfig == null ? new DiffConfig() : (DiffConfig)diffConfig.DeepClone();

            if (string.IsNullOrWhiteSpace(fragmentIdProperty))
            {
                BH.Engine.Reflection.Compute.RecordError($"The DiffConfig must specify a valid {nameof(fragmentIdProperty)}.");
                return(null);
            }

            // Clone for immutability
            List <IBHoMObject> currentObjs = currentObjects.ToList();
            List <IBHoMObject> pastObjs    = pastObjects.ToList();

            string customDataIdKey = fragmentType.Name + "_fragmentId";

            currentObjs.ForEach(o => o.CustomData[customDataIdKey] = o.GetIdFromFragment(fragmentType, fragmentIdProperty));
            pastObjs.ForEach(o => o.CustomData[customDataIdKey]    = o.GetIdFromFragment(fragmentType, fragmentIdProperty));

            return(DiffWithCustomId(pastObjs, currentObjs, customDataIdKey, diffConfig));
        }
コード例 #26
0
 public static Revision Revision(IEnumerable <IBHoMObject> objects, object streamId, string revisionName = null, string comment = null, DiffConfig diffConfig = null)
 {
     return(new Revision(Modify.PrepareForRevision(objects, diffConfig), ProcessStreamId(streamId), diffConfig, revisionName, comment));
 }
コード例 #27
0
        protected T ExtractItem <T>(string assemblyFile, string parentName, string typeName, DiffConfig config) where T : ICanAlign, new()
        {
            AssemblyDetail all = ExtractAll(assemblyFile, config);

            foreach (ICanCompare parent in all.Children)
            {
                if (parent.Name == parentName)
                {
                    T t = ListOperations.FindOrReturnMissing(parent.FilterChildren <T>(), typeName);
                    Log.Verbose("Extracted Item {0} : {1}", t.GetType().Name, t.ToString());
                    return(t);
                }
            }

            Assert.Inconclusive("Specified parent {0} was not found", parentName);
            return(default(T));
        }
コード例 #28
0
 protected AttributeDetail ExtractAttribute(string assemblyFile, string typeName, DiffConfig config)
 {
     return(ExtractItem <AttributeDetail>(assemblyFile, "Attributes", typeName, config));
 }
コード例 #29
0
 protected ResourceDetail ExtractResource(string assemblyFile, string typeName, DiffConfig config)
 {
     return(ExtractItem <ResourceDetail>(assemblyFile, "Resources", typeName, config));
 }
コード例 #30
0
 protected EnumDetail ExtractEnum(string assemblyFile, string typeName, DiffConfig config)
 {
     return(ExtractItem <EnumDetail>(assemblyFile, Subjects.NamespaceOne, typeName, config));
 }