📜 ⬆️ ⬇️

Experience developing a plugin for Yasca

In this article I want to share the experience of using one useful utility that allows you to automate the assembly and analysis of code quality. It will be about Yasca - free software, which is a small PHP engine and a set of utilities for performing Java, C ++ or PHP code analysis, including PMD, JLint and RATS. The very integration of the execution of these utilities is carried out by developing small plug-ins in PHP. The development process of such a plugin and will be discussed further.

To begin with, we need to achieve the functioning of Yasca itself. To do this is quite simple. Go to the download page and download the actual yasca and one of the codecs . Create a local directory (for example, c: / yasca) and simply unpack all the archives into it in turn. Immediately after this, the tool is ready to go. We type in the command line (or save to cmd-file) the command (replacing the ellipsis with the directory path with some Java or C ++ project):

yasca.exe -o ./Report ... 

After working for some time, Yasca forms the Report.html report containing comments on the coding style of our project. The report lines contain links to the source code and the only thing that is inconvenient is that when you click a link, we get to the beginning of the file, and it may be a bit tiring to search for the required line by number. That is what I propose to fix. Let the links position us immediately to the desired line of source code.

It is clear that we cannot turn this focus directly on the source code, but we can build temporary html files on their basis by forming a bookmark in each line, for which name we use the line number. At the same time, on the left, we will put line numbers to make it easier to navigate. It sounds scary, but in fact, is done quite simply. The plug-in itself (you will need to put it in the plugins folder, calling Mirror.php) will look like this:
')
 <?php /** * @extends Plugin * @package Yasca */ class Plugin_Mirror extends Plugin { public $valid_file_types = array("java", "c", "cpp", "h", "cs", "sql"); function rmdir_recurse($path) { $path= rtrim($path, '/').'/'; $handle = opendir($path); for (;false !== ($file = readdir($handle));) if($file != "." and $file != ".." ) { $fullpath= $path.$file; if( is_dir($fullpath) ) { $this->rmdir_recurse($fullpath); rmdir($fullpath); } else unlink($fullpath); } closedir($handle); } function execute() { $yasca =& Yasca::getInstance(); static $once = true; if ($once) { $this->rmdir_recurse('./Mirror'); } $once = false; if (!check_in_filetype($this->filename, $this->valid_file_types)) { return; } $filename = preg_replace('/\w:/', './Mirror', $this->filename) . ".html"; $dir_name = preg_replace('/[\\\\\\/][^\\\\\\/]+$/', '', $filename); if (!file_exists($dir_name)) { if (!mkdir($dir_name, 0777, true)) return; } if (file_exists($filename)) { unlink($filename); } if (!$handle = fopen($filename, 'w+', true) ) return; fwrite($handle,"<html><meta http-equiv=\"Content-Type\" content=\"text/html;charset=windows-1251\" /><head></head><body><pre>\n"); $line = 1; foreach ($this->file_contents as $file_line) { $str = $line; while (strlen($str)<5) { $str = " " . $str; } fwrite($handle,"<a name=$line></a>$str: $file_line<br>\n"); $line++; } fwrite($handle,"</pre></body></html>"); fclose($handle); } } ?> 

Now, after the next launch of yasca, we will receive copies of all analyzed files in the Mirror directory in the prepared in html form. In order to make these files useful, we will have to intervene in the course of building the report and replace the links to our version that they form. Fortunately, this code is also written in PHP. Go to the lib directory and find the HTMLGroupReport.php file used to create the report, by default. In this file, we find the fragment:

 fwrite($handle, "<a style=\"margin-right: 12px;\" source_code_link=\"true\" href=\"file://$filename\" target=\"_blank\" title=\"$filename\">$filename_base$line_number_field</a>" . "</td>"); 

And replace it with:

 $chg_file_name = getcwd(); $chg_file_name = preg_replace('/\\\\/', '/', $chg_file_name); $chg_file_name = preg_replace('/^\w:/', $chg_file_name . '/Mirror', $filename); if (preg_match('/\.java$|\.c$|\.cpp$|\.h$|\.cs$|\.sql$/i', $chg_file_name)) { fwrite($handle, "<a style=\"margin-right: 12px;\" source_code_link=\"true\" href=\"file://$chg_file_name.html#$line_number\" target=\"code\" title=\"$filename\">$filename_base$line_number_field</a>" . "</td>"); } else { fwrite($handle, "<a style=\"margin-right: 12px;\" source_code_link=\"true\" href=\"file://$filename\" target=\"_blank\" title=\"$filename\">$filename_base$line_number_field</a>" . "</td>"); } 

After that, run Yasca again and make sure that everything works. In terms of further automation, our imagination is not very limited. We, for example, had a plugin automating the assembly of a large C ++ project under Windows using MSBuild. Since the build itself took about an hour, a slight slowdown associated with the work of Yasca and the codecs did not play a role. But at the exit we received a report containing both Warning and comments on the Code Style, with convenient positioning in the source code.

Source: https://habr.com/ru/post/158229/


All Articles