Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
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);
        }