I'm working over some php library. I want to track the changes in the interfaces of classes library.
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
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With