/// <summary>
        /// Checks the compatibility of the locally-built API against a version on NuGet.
        /// This assumes the local package has already been built and is up-to-date.
        /// </summary>
        private static Level CheckCompatibility(ApiMetadata api, StructuredVersion version)
        {
            Console.WriteLine($"Differences from {version}");

            // TODO: Remove this try/catch when *everything* has a previous minor version on netstandard2.0.
            AssemblyDefinition oldMetadata;

            try
            {
                oldMetadata = Assemblies.LoadPackageAsync(api.Id, version.ToString(), null, null).Result;
            }
            catch (Exception e)
            {
                Console.WriteLine($"Unable to load {api.Id} version {version} from NuGet. Some possible causes:");
                Console.WriteLine("- Package was pre-netstandard2.0");
                Console.WriteLine("- Package was never published");
                Console.WriteLine("- nuget.org failure");
                Console.WriteLine($"Exception message: {e.Message}");
                Console.WriteLine($"Returning 'identical' as the change level; please check carefully before release.");
                return(Level.Identical);
            }
            var sourceAssembly = Path.Combine(DirectoryLayout.ForApi(api.Id).SourceDirectory, api.Id, "bin", "Release", "netstandard2.0", $"{api.Id}.dll");
            var newMetadata    = Assemblies.LoadFile(sourceAssembly);

            var diff = Assemblies.Compare(oldMetadata, newMetadata, null);

            diff.PrintDifferences(Level.Major, FormatDetail.Brief);
            diff.PrintDifferences(Level.Minor, FormatDetail.Brief);
            Console.WriteLine($"Diff level: {diff.Level}");
            Console.WriteLine();
            return(diff.Level);
        }
        protected DiffResult RunTest([CallerMemberName] string callerMemberName = null)
        {
            var s = new MemoryStream(s_dllBytes);

            // Must be read twice, as each assembly definition will be independently mutated during the test.
            s.Position = 0;
            var older = AssemblyDefinition.ReadAssembly(s);

            s.Position = 0;
            var newer = AssemblyDefinition.ReadAssembly(s);
            // Use this convention for test namespaces:
            // Test namespace is the name of the test type (e.g. `ClassMethodTest`) without the `Test` suffix,
            // followed by the name of the test method (e.g. `MethodAdded`), followed by `A` or `B` for the
            // original or new version of the code.
            var typeName      = GetType().Name;
            var testNamespace = $"{typeof(TestBase).Namespace}.{typeName.Substring(0, typeName.Length - "Test".Length)}.{callerMemberName}";

            // Run version compatibility checker.
            return(Assemblies.Compare(older, newer, testNamespace));
        }
Beispiel #3
0
        private static async Task <int> Main(string[] args)
        {
            CommandLineOptions options = null;
            var parsed = Parser.Default.ParseArguments <CommandLineOptions>(args);

            switch (parsed)
            {
            case Parsed <CommandLineOptions> success:
                options = success.Value;
                break;

            case NotParsed <CommandLineOptions> failure:
                // Errors will have already been shown.
                return(200);

            default:
                Console.WriteLine("Error: Unexpected command-line parse result.");
                return(201);
            }

            // Perform secondary validation
            if (!options.Validate())
            {
                return(1);
            }

            var assem0 = await LoadAsync(options, options.File1, options.Version1);

            var assem1 = await LoadAsync(options, options.File2, options.Version2);

            var diffs = Assemblies.Compare(assem0, assem1, null);

            if ((options.OutputBehavior & OutputBehavior.Major) != 0)
            {
                diffs.PrintDifferences(Level.Major, options.FormatDetail);
            }
            if ((options.OutputBehavior & OutputBehavior.Minor) != 0)
            {
                diffs.PrintDifferences(Level.Minor, options.FormatDetail);
            }

            int exitCode;

            switch (options.ExitCodeBehavior)
            {
            case ExitCodeBehavior.MajorOnly:
                exitCode = diffs.Major.Any() ? 2 : 0;
                break;

            case ExitCodeBehavior.MajorAndMinor:
                exitCode = diffs.Major.Any() ? 2 : diffs.Minor.Any() ? 1 : 0;
                break;

            default:
                exitCode = 0;
                break;
            }

            Console.WriteLine($"Diff level: {diffs.Level}");
            Console.WriteLine();

            return(exitCode);
        }