Skip to content

Commit

Permalink
first release
Browse files Browse the repository at this point in the history
  • Loading branch information
jhofm committed Dec 25, 2020
1 parent 31fad5a commit 27c8bea
Show file tree
Hide file tree
Showing 26 changed files with 5,389 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/.idea/
/vendor/
!/var/cache/.gitkeep
/var/cache/*
/*.puml
100 changes: 100 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# PhPuml

## About PhPuml

PhPuml is a console tool that creates PlantUML class diagram definitions (`*.puml`) from PHP code, written in PHP.

Here's a class diagram of the tool, created by itself:

![PhPuml class diagram](./doc/img/ph-puml.svg)
[<img src="./doc/img/ph-puml.svg" width="816">](./doc/img/ph-puml.svg)

And the [generated puml file](./doc/src/ph-puml.puml) the diagram is based on.

## Features

* Convenient installation via composer
* Packages from Namespaces
* Generates inheritance relationships for classes, interfaces and traits
* Generates class properties & method signatures, including type hints from @var doc comments
* Dependencies inferred from constructor argument types (assumes dependency injection)
* Associations inferred from new expressions (creates), throw statements (throws)
* Works on Linux (tested), Windows (tested), macOS (probably)

## Requirements

* PHP 7.4 only for now
* Composer 2

## Installation

The preferred way to install PhPuml globally through composer.

```console
$ composer global require jhofm/ph-puml
```

If you already have composer's global vendor/bin folder in your PATH, the tool can be executed by calling the script ```ph-puml```.
Otherwise the executable can be found at ``~/.composer/vendor/bin/ph-puml``.

Alternatively you can also clone this repository and install the composer dependencies yourself.

```console
$ git clone git@github.com:jhofm/ph-puml.git
$ cd ph-puml
$ composer install
$ ./bin/ph-puml
```

## Quick Start

The `ph-puml` script will output PlantUML code describing all PHP files found in the current
folder. Alternatively it accepts a relative or absolute path to a target directory or file as an argument.

```bash
$ ph-puml src/tests
```

The resulting PlantUML code is written to the console (and can of course be piped into a file instead).

```bash
$ ph-puml > class.puml
```

If the target path is a directory, PhPuml will recursively find files with the file extension ```.php``` there.
Folders called `vendor` in target directory are ignored by default.
If you want to include a vendor folder, disable the exclusion regex like this:

```console
$ ph-puml --exclude ""
```

You can also define your own exclusions (only regular expressions are supported currently):

```console
$ ph-puml --exclude "~^foo~" --exclude "~bar$~"
```

PhPuml uses `symfony/command`, so you can always check out the command's help page including all supported arguments and options.

```console
$ ph-puml -h
```

## Limitations

* PhPuml is able to handle huge amounts of code files, but for your sanity's sake i'd advise using it on smaller packages.
* Cleaner code will yield better results. Typehints and Namespaces help a whole lot, for example.
* There's a lot of polishing still to be done, like inferring additional relation types or providing more customisations.
* When parsing directories, only files with the file extension ``*.php`` are currently included.
* Auto generated class diagrams will probably never exactly meet your needs, but at least they should provide a starting point and save you some mind-numbing work.

## Troubleshooting

* `Uncaught Error: Class Composer\InstalledVersions not found`: PhPuml requires Composer 2
* `require(): Failed opening required ...`: Run composer install

## Acknowledgements

This would have been exponentially more difficult to do without [Nikita Popov](https://github.com/nikic)'s [PHP-Parser](https://github.com/nikic/PHP-Parser),
so many thanks for that. And [symfony](https://github.com/symfony) helped a lot, as usual.
36 changes: 36 additions & 0 deletions bin/ph-puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env php
<?php

require __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';

use Composer\InstalledVersions;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Console\Application;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;

// build & cache DI container
$container = (function (): ProjectServiceContainer {
$package = InstalledVersions::getRootPackage();
$cachePath = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'var' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'container_' . $package['reference'] . '.php';
if (!file_exists($cachePath)) {
$containerBuilder = new ContainerBuilder();
$loader = new YamlFileLoader(
$containerBuilder,
new FileLocator(
dirname(__DIR__) . DIRECTORY_SEPARATOR . 'config'));
$loader->load('services.yml');
$containerBuilder->compile();
file_put_contents($cachePath, (new PhpDumper($containerBuilder))->dump());
}
require_once $cachePath;
return new ProjectServiceContainer();
})();

// add command name to input arguments
$args = array_slice($_SERVER['argv'], 1);
array_unshift($args, $_SERVER['argv'][0], 'ph-puml');
$_SERVER['argv'] = $args;

$container->get(Application::class)->run();
32 changes: 32 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"name": "jhofm/ph-puml",
"description": "Generates PlantUML class diagrams from PHP code",
"type": "project",
"license": "MIT",
"authors": [
{
"name": "Johannes Hofmann",
"email": "hofmann.johannes@gmail.com"
}
],
"bin": ["bin/ph-puml"],
"require-dev": {
"phpunit/phpunit": "^9.5"
},
"require": {
"ext-json": "*",
"symfony/console": "^5.2",
"nikic/php-parser": "^4.10",
"symfony/dependency-injection": "^5.2",
"symfony/process": "^5.2",
"symfony/finder": "^5.2",
"jhofm/flysystem-iterator": "^2.2",
"symfony/config": "^5.2",
"symfony/yaml": "^5.2"
},
"autoload": {
"psr-4": {
"Jhofm\\PhPuml\\": "src"
}
}
}
Loading

0 comments on commit 27c8bea

Please sign in to comment.