Beispiel #1
0
        private static UpversionType AnalyzeMethods(IList <MethodSpec> oldMethods, IList <MethodSpec> newMethods)
        {
            UpversionType maxUpversionType = UpversionType.Patch;

            foreach (MethodSpec oldMethod in oldMethods)
            {
                MethodSpec newMethod = newMethods
                                       .FirstOrDefault(field => field.Name.Name.Equals(oldMethod.Name.Name, StringComparison.InvariantCulture));
                if (newMethod == null)
                {
                    return(UpversionType.Major);
                }

                if (!newMethod.ReturnType.Equals(oldMethod.ReturnType, StringComparison.InvariantCulture))
                {
                    return(UpversionType.Major);
                }

                // Check parameters
                bool isMajorChange = NapackAnalyst.AnayzeParameters(oldMethod.Parameters, newMethod.Parameters);
                if (isMajorChange)
                {
                    return(UpversionType.Major);
                }
            }

            if (maxUpversionType == UpversionType.Patch && newMethods.Count != oldMethods.Count)
            {
                return(UpversionType.Minor);
            }

            return(maxUpversionType);
        }
Beispiel #2
0
        private static UpversionType AnalyzeConstructors(IList <ConstructorSpec> oldConstructors, IList <ConstructorSpec> newConstructors)
        {
            UpversionType maxUpversionType = UpversionType.Patch;

            foreach (ConstructorSpec oldConstructor in oldConstructors)
            {
                // Constructor matching is complicated as all constructors have the same name, but different parameters.
                // For now, perform an inefficient n^2 matching by comparing each old constructor against each new one.
                bool anyWithoutMajorChanges = false;
                foreach (ConstructorSpec newConstructor in newConstructors)
                {
                    if (!NapackAnalyst.AnayzeParameters(oldConstructor.Parameters, newConstructor.Parameters))
                    {
                        anyWithoutMajorChanges = true;
                        break;
                    }
                }

                if (!anyWithoutMajorChanges)
                {
                    return(UpversionType.Major);
                }
            }

            if (maxUpversionType == UpversionType.Patch && newConstructors.Count != oldConstructors.Count)
            {
                return(UpversionType.Minor);
            }

            return(maxUpversionType);
        }
Beispiel #3
0
        private static UpversionType AnalyzeInterface(InterfaceSpec oldInterfaceSpec, InterfaceSpec newInterfaceSpec)
        {
            UpversionType maxUpversionType = UpversionType.Patch;

            if (newInterfaceSpec == null)
            {
                // The new spec removed a publically facing class.
                return(UpversionType.Major);
            }

            UpversionType upversionType = NapackAnalyst.AnalyzeProperties(oldInterfaceSpec.Properties, newInterfaceSpec.Properties);

            if (upversionType == UpversionType.Major)
            {
                return(upversionType);
            }
            else if (upversionType == UpversionType.Minor)
            {
                maxUpversionType = UpversionType.Minor;
            }

            upversionType = NapackAnalyst.AnalyzeMethods(oldInterfaceSpec.Methods, newInterfaceSpec.Methods);
            if (upversionType == UpversionType.Major)
            {
                return(upversionType);
            }
            else if (upversionType == UpversionType.Minor)
            {
                maxUpversionType = UpversionType.Minor;
            }

            return(maxUpversionType);
        }
Beispiel #4
0
        /// <summary>
        /// Determines the requried upversioning when code transitions from the old Napack to the new Napack.
        /// </summary>
        /// <remarks>
        /// Major == breaking changes.
        /// Minor == publically-facing API was added (but not changed or removed) from the new Napack.
        /// Patch == The publically-facing API is identical between both Napacks, excluding documentation.
        /// </remarks>
        public static UpversionType DeterminedRequiredUpversioning(NapackSpec oldNapack, NapackSpec newNapack)
        {
            UpversionType maxUpversionType = UpversionType.Patch;

            foreach (ClassSpec oldClassSpec in oldNapack.Classes)
            {
                ClassSpec newClassSpec = newNapack.Classes
                                         .FirstOrDefault(cls => cls.Name.Name.Equals(oldClassSpec.Name.Name, StringComparison.InvariantCulture));
                UpversionType upversionType = NapackAnalyst.AnalyzeClass(oldClassSpec, newClassSpec);
                if (upversionType == UpversionType.Major)
                {
                    // Exit early, as we found a breaking change.
                    return(UpversionType.Major);
                }
                else if (upversionType == UpversionType.Minor)
                {
                    maxUpversionType = UpversionType.Minor;
                }
            }

            foreach (InterfaceSpec oldInterfaceSpec in oldNapack.Interfaces)
            {
                InterfaceSpec newInterfaceSpec = newNapack.Interfaces
                                                 .FirstOrDefault(cls => cls.Name.Name.Equals(oldInterfaceSpec.Name.Name, StringComparison.InvariantCulture));
                UpversionType upversionType = NapackAnalyst.AnalyzeInterface(oldInterfaceSpec, newInterfaceSpec);
                if (upversionType == UpversionType.Major)
                {
                    // Exit early, as we found a breaking change.
                    return(UpversionType.Major);
                }
                else if (upversionType == UpversionType.Minor)
                {
                    maxUpversionType = UpversionType.Minor;
                }
            }

            // No APIs added in the prior classes. Did the new package add classes?
            if (maxUpversionType == UpversionType.Patch && (newNapack.Classes.Count != oldNapack.Classes.Count || newNapack.Interfaces.Count != oldNapack.Interfaces.Count))
            {
                maxUpversionType = UpversionType.Minor;
            }

            return(maxUpversionType);
        }
Beispiel #5
0
        private static UpversionType AnalyzeClass(ClassSpec oldClassSpec, ClassSpec newClassSpec)
        {
            UpversionType maxUpversionType = UpversionType.Patch;

            if (newClassSpec == null)
            {
                // The new spec removed a publically facing class.
                return(UpversionType.Major);
            }

            // Check if any modifier changes force a major (breaking) change.
            if ((!oldClassSpec.IsAbstract && newClassSpec.IsAbstract) ||
                (oldClassSpec.IsStatic != newClassSpec.IsStatic) ||
                (!oldClassSpec.IsSealed && newClassSpec.IsSealed))
            {
                return(UpversionType.Major);
            }

            // Verify all old fields exist
            UpversionType upversionType = NapackAnalyst.AnalyzeFields(oldClassSpec.PublicFields, newClassSpec.PublicFields);

            if (upversionType == UpversionType.Major)
            {
                return(upversionType);
            }
            else if (upversionType == UpversionType.Minor)
            {
                maxUpversionType = UpversionType.Minor;
            }

            upversionType = NapackAnalyst.AnalyzeProperties(oldClassSpec.PublicProperties, newClassSpec.PublicProperties);
            if (upversionType == UpversionType.Major)
            {
                return(upversionType);
            }
            else if (upversionType == UpversionType.Minor)
            {
                maxUpversionType = UpversionType.Minor;
            }

            upversionType = NapackAnalyst.AnalyzeConstructors(oldClassSpec.PublicConstructors, newClassSpec.PublicConstructors);
            if (upversionType == UpversionType.Major)
            {
                return(upversionType);
            }
            else if (upversionType == UpversionType.Minor)
            {
                maxUpversionType = UpversionType.Minor;
            }

            upversionType = NapackAnalyst.AnalyzeMethods(oldClassSpec.PublicMethods, newClassSpec.PublicMethods);
            if (upversionType == UpversionType.Major)
            {
                return(upversionType);
            }
            else if (upversionType == UpversionType.Minor)
            {
                maxUpversionType = UpversionType.Minor;
            }

            // Analyze classes recursively.
            foreach (ClassSpec oldClass in oldClassSpec.PublicClasses)
            {
                ClassSpec newClass = newClassSpec.PublicClasses
                                     .FirstOrDefault(cls => cls.Name.Name.Equals(oldClass.Name.Name, StringComparison.InvariantCulture));
                upversionType = NapackAnalyst.AnalyzeClass(oldClass, newClass);
                if (upversionType == UpversionType.Major)
                {
                    return(upversionType);
                }
                else if (upversionType == UpversionType.Minor)
                {
                    maxUpversionType = UpversionType.Minor;
                }
            }

            if (maxUpversionType == UpversionType.Patch && oldClassSpec.PublicClasses.Count != newClassSpec.PublicClasses.Count)
            {
                maxUpversionType = UpversionType.Minor;
            }

            return(maxUpversionType);
        }