JustAssembly icon indicating copy to clipboard operation
JustAssembly copied to clipboard

Use from command line for enforcement of SemanticVersioning

Open Lexcess opened this issue 7 years ago • 7 comments

We use SemanticVersioning (http://semver.org) for all our software assets and I wonder if this utility could (or perhaps already allows) for it to be used as part of a process for sanity checking that.

Specifically it'd be useful to:

  • Submit a target and comparison assembly via the command line
  • Output whether to the command line whether there are:
    • Major (breaking signature) changes
    • Minor (additive signature/type) changes
    • Patch (only internal implementation) changes

Even better would be to be able to submit two sets/paths worth of assemblies and for the tool indicate the highest common denominator (i.e. eight 'patch' and one 'minor' result equals 'minor').

I understand this is almost certainly a feature request and quite possibly out of the scope of what you intend for the tool. Yet having this utility as a repeatable process would elevate it from something of a novelty/emergency utility to a concrete part of our pipeline. Love to hear your thoughts.

Lexcess avatar Apr 07 '17 13:04 Lexcess

That would be a really useful feature. Being part of an automated build pipeline is a natural next step for JustAssembly.

We have not really limited the scope of the tool in any way. Rather unfortunately, what is limited at present is the resources we can invest in the tool. That is why we open sourced JustAssembly completely so that the lack of resources would not hinder its development. We would be more than glad to help (with advise, API changes, etc.) any party that is interested in adding a feature.

For somebody unfamiliar with JustAssembly code base a really good starting place for researching such a feature would be the IDiffItem interface.

tsviatko avatar Apr 24 '17 17:04 tsviatko

Thanks @tsviatko

Ok so that is interesting.

Looking at the interface you use a combination of difftype and is breaking to determine the level of change. Is this at method signature or content level?

For example is

string Foo()
{
    return new Object().ToString();
}

to

string Foo()
{
    return new Object().ToString().ToUpper();
}

A non-change or a Modified + Non-Breaking change?

Assuming that it is method signature based then would the following table make sense as a mapping?

DiffType IsBreaking SemVer
None - Patch
New No Minor
Modified No Minor
Deleted No Minor*
New Yes Major
Deleted Yes Major
Modified Yes Major

* I suspect this combination isn't possible.

Lexcess avatar Apr 25 '17 13:04 Lexcess

Hi @Lexcess,

First and foremost - please, excuse us for the huge delay on our answer.

Looking at the interface you use a combination of difftype and is breaking to determine the level of change. Is this at method signature or content level?

IDiffItem is used to represent signature changes. So in your example the result should be a non-change.

Since command-line support was added in #24, the task becomes even easier, since there is no need for infrastructure changes - project creations, configuration, etc - they are already done.

For calculating differences APIDiffHelper.GetAPIDifferences can be used. Several points that should be noted:

  • This method returns null if there are no differences between the 2 assemblies.
  • Only PUBLIC API diffs are considered, i.e. if an assembly has a deleted internal method, this will not be considered as an change and the method will still return null.
  • The IsBreakingChange property of the topmost IDiffItem (in this case it should be AssemblyDiffItem) has the aggregated value of all its children's IsBreakingChange properties. That means if the only difference between 2 assemblies is removed public method (which is a breaking change) then the IsBreakingChange property of the result of GetAPIDifferences should hold true.

Considering all of the above, the mapping table you proposed becomes even simpler:

IDiffType IsBreakingChange SemVer
null - Patch
non-null false Minor
non-null true Major

If you need more help or information, please, do not hesitate to ask.

atdimitrov avatar May 16 '17 16:05 atdimitrov

@tsviatko I'm looking to see if anyone on our team can pick this up in the next few weeks. No guarantees but we'd certainly like to use it in this manner.

Lexcess avatar Jun 19 '17 17:06 Lexcess

That'd be great.

Here are a couple of things you might find helpful in the process.

In the meantime we have added command line diff with XML output #16 . The output looks something like this:

<Assembly Name="Telerik.Pivot.Core, Version=2013.2.923.45, Culture=neutral, PublicKeyToken=5803cfa389c90ce7" DiffType="Modified">
  <Module Name="Telerik.Pivot.Core.dll" DiffType="Modified">
    <DeclarationDiffs>
      <AssemblyReference Name="Telerik.Windows.Controls, Version=2013.2.724.45, Culture=neutral, PublicKeyToken=5803cfa389c90ce7" DiffType="Deleted" />
    </DeclarationDiffs>
<Type Name="Telerik.Pivot.Core.CalculatedAggregateDescription" DiffType="Modified">
      <DeclarationDiffs>
        <DiffItem DiffType="Modified">Member is more visible.</DiffItem>
      </DeclarationDiffs>
      <Property Name="CalculatedField" DiffType="Modified">
        <Method Name="get" DiffType="Modified">
          <DeclarationDiffs>
            <DiffItem DiffType="Modified">Method changed to virtual.</DiffItem>
          </DeclarationDiffs>
        </Method>
      </Property>
      <Method Name="CreateAggregate()" DiffType="Deleted" />
    </Type>
  </Module>
</Assembly>​

Looking at it a quick and somewhat dirty way of implementing this feature would be based on this XML output entirely. In theory you could get the Major/Minor/Patch classification just by analyzing the XML without touching JustAssembly code. In practice you will have to touch the code to add the access modifiers to the XML (so that you know whether it's public API that changes). That is a very mild touch and should be easy, though. Attributes would be a thing to keep an eye on, too since they can change the public API and I don't really have it at the top of my head how we handle them in this XML.

Other than that you could implement the folder comparison feature in command line (should be really easy too). That's just a convenience though. If not present it could be easily replaced by a batch file equivalent in the build that iterates over all output assemblies.

So all in all, it should be pretty easy to come up with a first working prototype of that feature.

tsviatko avatar Jun 19 '17 20:06 tsviatko

@Lexcess You all haven't done anything with this, correct? I'm looking into this right now and can pick it up if not. we are also looking at the folder comparison feature. we have modified it to work for us, but would like to make it more generic. I'll put that in a separate issue/PR though.

omosubi avatar Feb 06 '18 00:02 omosubi

@omosubi No, we ran it past our teams and in the end there wasn't enough interest in doing the work. It'd be a great feature to have though.

If you need any help bouncing ideas/implementation we'd be happy to help there, otherwise good luck!

Lexcess avatar Feb 07 '18 12:02 Lexcess