Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you know the differences in the interfaces between two different versions?

I'm working over some php library. I want to track the changes in the interfaces of classes library.

  • Yes, i'm using GIT. But diff produces more information than i need.
  • I was trying to compare two versions with phpDocumentor.

    phpdoc project:parse -d folder

produce xml file with structure of project interface. I can compare this xml file with another. But these contain more information than I want. Like line numbers, file hash and so on.

So, I want to compare two commits, branches or even forks and find out differences of their interfaces.

Example to compare: http://pastebin.com/1H61dJBT

It also important to know when to change Major version.

MAJOR version when you make incompatible API changes...

http://semver.org/spec/v2.0.0.html

like image 395
sectus Avatar asked Mar 22 '13 00:03

sectus


2 Answers

I reckon you want to build a workflow around PHP Smart Differencer

An example of the PHP Smart Differencer's results can be seen here. This page contains an example of the output generated by SD's PHP Smart Differencer tool when applied to an original file and an updated version of the same file.

If you really want to roll your own, you might build it around PHP-Parser which will likely give you a bit more precision, but you would need to generate your own comparison algorithms where SmartDifferencer's tool already has that built in.

Either of these will give you what it seems you are looking for.

like image 184
bubba Avatar answered Sep 28 '22 06:09

bubba


Plain diff reports differences in terms of text lines. Software is defined in terms of code structures. The mismatch between source-code-as-text-lines and source as structures is what make diff's output hard to understand.

You could instead compare the interface definitions with Semantic Designs (my company's) SmartDifferencer.

This reports the minimal edits on code structures (not lines) to convert one piece of (PHP) code into another. Changes to names of interface functions, inserted or deleted parameters, become pretty obvious. Line breaks aren't relevant and don't influence SmartDifferencer's results; neither are comments unless you insist they are. (SmartDifferencer isn't limited to PHP; there's versions for many languages).

EDIT: OP wanted to know what SmartDifferencer did on a specific example of an interface change (before and after PHP files). What follows are his two sample files, their SmartDifferencer output, and Unix-diff output. I remark there's a lot of changes in these pretty small example files.

First interface:

<?php
// ----- first version -----
namespace vendor\package;

class someClass
{
private $c;
public function __construct($a, $b)
    {
    $c = $a + $b;
    }
/**
 * @return string
 */
public function returnC()
    {
    return $this->c;
    }
public function saySomething()
    {
    echo 'something';
    }
}

Modified interface file

<?php
// ----- second version -----
namespace vendor\package;

class someClass
{
private $a, $b;

public function __construct($a, $b)
    {
    $this->a = $a;
    $this->b = $b;
    }

public function saySomething($something = 'something')
    {
    echo $something;
    }

/**
 * @return integer
 */
public function returnC()
    {
    return $this->a + $this->b;
    }

}

Smart Differencer output (M.N means "Line M, column N"):

C:>DMSSmartDifferencer PHP~PHP5 \temp\first_version.php \temp\second_version.php
Copyright (C) 2009-2012 Semantic Designs; All Rights Reserved
PHP~PHP5 SmartDifferencer Version 1.0.14
Copyright (C) 2012 Semantic Designs, Inc; All Rights Reserved; SD Confidential
Powered by DMS (R) Software Reengineering Toolkit
*** Unregistered SmartDifferencer Version 1.0
*** Operating with evaluation limits.

*** Parsing file C:/temp/first_version.php ...
*** Parsing file C:/temp/second_version.php ...
*** Creating suffix tree ...
*** Determining maximal pairs ...
*** Sorting maximal pairs ...
*** Determining differences ...
*** Printing edits ...
Substitute 7.13-7.14 by 7.13-7.18
<            $c
>            $a, $b
Substitute 10.9-10.21 by 11.9-12.22
<        $c = $a + $b;
>        $this->a = $a;
>        $this->b = $b;
At 15.12 insert 15.12-18.9 moving 19.21-19.32 to 15.21-15.32
>           function saySomething($something = 'something')
>        {
>        echo $something;
>        }
Delete 15.12-18.9 at 15.12 moving 15.21-15.27 to 23.21-23.27
<           function returnC()
<        {
<        return $this->c;
<        }
At 19.21 insert 23.21-23.27 moving 15.21-15.27 to 23.21-23.27
>                    returnC
Delete 19.21-19.32 at 23.21 moving 19.21-19.32 to 15.21-15.32
<                    saySomething
Substitute 21.9-21.25 by 25.9-25.35
<        echo 'something';
>        return $this->a + $this->b;
Exiting with final status 1.

You should see that SmartDifferencer is focused on the deltas in the code structure, not deltas in the lines. The first thing you notice is that SmartDifferencer completely ignored the comments, as they have no impact on what the code does.

But the most glaring example of this in the unix diff below is the multiple diffs that lump a delta at the end of one function with a delta at beginning of another; no programmer explains differences in code that way. Such a confused diff makes for confusing reading when trying to understand what really changed.

Output from unix-style diff:

C:>diff \temp\first_version.php \temp\second_version.php
2c2
< // ----- first version -----
---
> // ----- second version -----
7c7,8
<     private $c;
---
>     private $a, $b;
>
10c11,17
<         $c = $a + $b;
---
>         $this->a = $a;
>         $this->b = $b;
>         }
>
>     public function saySomething($something = 'something')
>         {
>         echo $something;
11a19
>
13c21
<      * @return string
---
>      * @return integer
17,21c25
<         return $this->c;
<         }
<     public function saySomething()
<         {
<         echo 'something';
---
>         return $this->a + $this->b;
22a27
>

What neither SmartDifferencer nor diff do, is tell you that the behavior of an interface changed, because the code on which it depends changed. The only way to do that is a static semantic analysis of all code directly or indirectly supporting the interface, and that's a lot harder problem.

like image 27
Ira Baxter Avatar answered Sep 28 '22 08:09

Ira Baxter