Code Monkey home page Code Monkey logo

tombstone's Introduction

scheb/tombstone

Implements the concept of tombstones for dead code detection in PHP.

The library provides you with a toolbox to place, track and evaluate tombstones in your code.

Build Status Code Coverage Latest Stable Version Monthly Downloads Total Downloads License

Logo

What are Tombstones?

To get the basic idea, watch David Schnepper's 5 minute talk from Velocity Santa Clara 2014.

Tombstone Youtube Video

When you want to identify and clean-up dead code in a project, static code analysis tools are the weapon of choice. But these tools have some limitations, especially in a dynamic language like PHP:

  • They can only tell you, if a piece of code is referenced, not if it's actually used
  • They cannot resolve dynamic or generated call paths

Tombstones provide a way to track if a piece of code is actually invoked. They are executable markers in your code, that you can place where you suspect dead code. Then, you collect tombstone invocations on production. After a while, the logs will tell you, which tombstones are dead and which ones aren't (the so called "vampires").

Installation

The library consists of multiple components, that need to be installed and configured independently:

Read how to install scheb/tombstone-logger for placing and logging tombstones in your code.

Read how to install scheb/tombstone-analyzer, which takes log data from scheb/tombstone-logger to generate reports in various formats. For example an HTML report:

Dashboard view Code view

Security

For information about the security policy and know security issues, see SECURITY.md.

Contributing

Want to contribute to this project? See CONTRIBUTING.md.

License

This software is available under the MIT license.

Acknowledgments

The library is heavily inspired by Nestoria.com's implementation of the tombstone concept.

Thanks to Jordi Boggiano for creating Monolog, from where I lend the handler/formatter concept.

The tombstone graphic is based on a licensed illustration by "lemonadeserenade".

Support Me

I'm developing this library since 2015. I love to hear from people using it, giving me the motivation to keep working on my open source projects.

If you want to let me know you're finding it useful, please consider giving it a star โญ on GitHub.

If you love my work and want to say thank you, you can help me out for a beer ๐Ÿป๏ธ via PayPal.

tombstone's People

Contributors

dav-m85 avatar ghispi avatar jawira avatar jimtools avatar lyudmild avatar rob-rg-schwarzberg avatar scheb avatar simoheinonen avatar swarrenwecareconnectorg avatar topikito avatar x-coder264 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tombstone's Issues

Having a gravedigger ?

Hi @scheb, first let me tell you this is a really fine piece of software, really love the idea.

I'm going to run tombstone on a set of production servers, and I'm thinking about how to generate reports efficiently. My problem is that the analyzer need both the log and the sources to be executed, making me checking out the code on the same machine as the analyzer.

I think it could be avoided by creating a "gravedigger" command which detects tombstones and send them in the log. This simplifies usage, I just need to run the gravedigger on each deploy instead of having to setup a specific build job (not impossible, but gosh I'm lazy).

Do you think it is feasible ?

Remove sebastian/finder-facade dependency

The tombstone package depends on sebastian/finder-facade, which is nowadays abandoned and the 2.0 version is not compatible with 8.0. We should migrate to a replacement, likely directly using symfony/finder (instead of using it through the facade) would be the best choice.

If someone wants to pick this up, feel free propose a solution.

Dependency Conflict Issue

Package version: 1.5.2

Description
There is an interesting consequence of using the phpunit/php-text-template when a project already has PHPUnit installed which is almost certain. you will only get the newer packages with PHP version <7.4 due to a conflict with PHPUnit version of phpunit/php-text-template it wants v3.

  • PHP <7.4, Package: 1.5.2
  • PHP 7.4, Package: 0.19.0
  • PHP 8+, Package: 0.8.0

To Reproduce

  1. copy example composer.json into an empty directory
  2. run composer install
  3. run composer require scheb/tombstone
  4. read the output of the installed version.

Additional Context
composer.json

{
    "name": "dependecy/issue",
    "type": "project",  
    "license": "MIT",
    "require": {
        "php": "~8.0"
    },
    "config": {
        "platform": {
            "php": "8.0"
        }
    },
    "require-dev": {
        "phpunit/phpunit": "^7.0|^8.0|^9.5|^10.5|^11.0"
    }
}

Output

./composer.json has been updated
Running composer update scheb/tombstone
Loading composer repositories with package information
Updating dependencies
Lock file operations: 2 installs, 0 updates, 0 removals
  - Locking psr/log (1.1.4)
  - Locking scheb/tombstone (0.8.0)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 2 installs, 0 updates, 0 removals
  - Installing psr/log (1.1.4): Extracting archive
  - Installing scheb/tombstone (0.8.0): Extracting archive
1 package suggestions were added by new dependencies, use `composer suggest` to see details.
Generating autoload files
25 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
No security vulnerability advisories found.
Using version ^0.8.0 for scheb/tombstone

Custom tombstone extractors

Idea

The analyzer is scanning the source code for calls to the tombstone function. This is how the analyzer gets it's list of "active tombstones". There might be reasons why you'd want to generate the list differently, or extend the list with additional tombstone locations* which cannot be detected by the extractor. A configuration option to register a custom extractor would be the solution.

(* One idea that I had for this was "virtual tombstones". Creating a tombstone that is actually not in the source code, but pretend as if it was there. For example you want all "Controller" classes automatically tagged with a virtual tombstone and every time the application calls a controller, you programmatically log a call to that virtual tombstone. You would get a report that shows which controllers are in use.)

If this idea would be useful to you, give it a +1

StackTraceFrame->getLine returns the last line on multi-line method calls

When retrieving the line information of a StackTraceFrame where the call of the frame is something like:

$object->someMethod(
  $argumentOne,
  $argumentTwo,
  $argumentThree,
);

inside each of the StackTraceFrames of the generated Vampire, the method getLine() shows the line of the last argument (4) instead of the line where the method name is (1).

Shouldn't it be the other way around?

Automation to Place Tombstones and Clean-Up Dead Code

Idea

I'd like to provide some automation to

  1. add tombstones to a codebase
  2. remove dead code from the codebase based on the results from the tombstone library

Since Rector is the standard library for PHP code migrations now, I thought it would be a good thing to use the Rector platform, rather than building my own little code migrations tool.

In detail, it would need to provide 2 rectors:

1. Setting Tombstones

The first rector would add tombstone() function calls to each public method. There could be potentially additional filtering options, which public method to target.

public function foo() {
    // ... Some code here
}

Result after rector was applied:

public function foo() {
    tombstone();
    // ... Some code here
}

2. Deleting Dead Code

The second rector would take a result from the tombstone library (transfer format TBD), providing the information which methods are detected as "dead code". The rector would remove these dead methods from the code.


If this idea would be useful to you, give it a +1

Custom matching strategies

Idea

The analyzer currently has 2 maching strategies:

  • By position (file+line) and the tombstone arguments
  • By surrounding method and the tombstone arguments

You maybe would want to have additional matching strategies for your application. So add configuration option register custom matching strategies to the analyzer.

If this idea would be useful to you, give it a +1

Configurable tombstone function name

Idea

Currently the tombstone function name is hardcoded to tombstone (a function within the global scope). Make that function configurable and allow having multiple tombstone functions. Multiple tombstone functions would provide more flexibility, e.g.

  • You don't want a function in the global scope, but use something namespaced instead
  • Have a function that always logs invocations vs. have a function that randomly logs (sampling)
  • Use different tombstones for different purposes

If this idea would be useful to you, give it a +1

Todo

  • Add function name to Tombstone class
  • Log tombstone function name
  • Add analyzer config option for tombstone functions names, pass these to the extractor
  • Add analyzer config option to use tombstone function name for matching tombstones (or not, to treat all tombstone functions as if they're all the same function)

HTML report with wrong bootstrap version

Package version: 1.5.0

Description

When we try to generate HTML report output we have an unformatted document.

Checking the CSS files, we can see that the minified bootstrap is in version 4.5.2, and inside HTML report templates we are trying to link version 4.1.3, which tries to load a different version and break the beautiful output. May the best option is remove the version from HTML files.

To Reproduce

Generate a tombstone-analyzer output with the html option and try to see the results.

Additional Context

One HTML template:
https://github.com/scheb/tombstone/blob/1.x/src/analyzer/Report/Html/Template/dashboard.html.dist#L7

Bootstrap version on CSS folder:
https://github.com/scheb/tombstone/blob/1.x/src/analyzer/Report/Html/Template/css/bootstrap.min.css#L2

Remove line from crc32 to be able to track functions in changed files

return crc32($this->file->getReferencePath()."\n".$this->line."\n".$this->functionName."\n".implode(',', $this->arguments));

When we save the logger, we use the tombstone hash to save the file log. As we are using the current line call, if we modify the file for any purpose, the line could change so, when we run a new tombstone-analyzer routine we will have one deleted tombstone call and a new one dead call.

So, for this situation, can we consider removing the line from the tombstone hash?

Psalm violition

Package version: 1.5.2

Description
There are several issues found by Psalm when running on the main branch this will be an issue/annoyance when dealing with future PR's

update
This is only when using v5 of the package, sorry I didn't notice sooner.

To Reproduce

  • Run ./vendor/bin/psalm --no-progress
  • View output

Additional Context

./vendor/bin/psalm --no-progress

...

------------------------------
17 errors found
------------------------------
315 other issues found.
You can display them with --show-info=true
------------------------------

Checks took 0.05 seconds and used 5.589MB of memory
No files analyzed
Psalm was able to infer types for 91.2313% of the codebase

Failing test ensureDirectoryCreated_directoryAlreadyCreated_doNothing

Package version: 1.5.2

Description

PHP 7.2
Composer 2.2
PHPUnit 8.5.35

There is an issue with one of the tests when using PHP 7.2

PHPUnit 8.5.35 by Sebastian Bergmann and contributors.

  Warning - The configuration file did not pass validation!
  The following problems have been detected:

  Line 13:
  - Element 'coverage': This element is not expected.

  Test results may not be as expected.


...............................................................  63 / 205 ( 30%)
.....E......................................................... 126 / 205 ( 61%)
............................................................... 189 / 205 ( 92%)
................                                                205 / 205 (100%)

Time: 453 ms, Memory: 20.00 MB

There was 1 error:

1) Scheb\Tombstone\Tests\Analyzer\Report\FileSystemTest::ensureDirectoryCreated_directoryAlreadyCreated_doNothing
Error: Call to undefined method PHPUnit\Framework\TestCase::assertDirectoryDoesNotExist()

/tmp/app/tests/TestCase.php:30
/tmp/app/tests/Analyzer/Report/FileSystemTest.php:61
phpvfscomposer:///tmp/app/vendor/phpunit/phpunit/phpunit:97

ERRORS!
Tests: 205, Assertions: 496, Errors: 1

To Reproduce

  • create .dockerignore and dockerfile
  • run docker build -t tombstone:alpine .
  • execute the image docker run --rm -it tombstone:alpine

Additional Context

vendor/
composer.lock
FROM php:7.2-cli-alpine

WORKDIR /tmp/app
RUN apk update && \
    apk add $PHPIZE_DEPS git zlib-dev && \
    docker-php-ext-install -j$(nproc) zip

COPY --chown=www-data:www-data --from=public.ecr.aws/docker/library/composer:2.2 /usr/bin/composer /usr/bin/composer

COPY --chown=www-data:www-data . /tmp/app
RUN --mount=type=cache,target=/home/www-data/.composer/cache \
    composer install && \
    chown www-data:www-data -R ./vendor/bin

USER www-data

ENTRYPOINT [ "/tmp/app/vendor/bin/phpunit" ]

HTML report missing figures on "Source" and "Dashboard" pages

Package version: 1.5.2

Description

When generating the HTML report using the analyzer, the "Source" figures aren't populated and the headline figures on "Dashboard" are missing.

The tombstone entries are logged fine when they're hit and the analyzer appears to scan the codebase fine.

We've wrapped the call to the tombstone() function with our own static method, could this be the cause? Tombstone::check();

To Reproduce

  1. Create the tombstone.yml file:
source_code:
  root_directory: /usr/local/www
logs:
  directory: ./tmp/tombstones
report:
  html: ./tmp/report/
  1. Run the analyzer

Additional Context

"Source" screen:
image

"Dashboard" screen:
image

Support class methods as tombstone functions

As noted in the documentation you need to include the file defining the tombstone function as early as possible. In larger projects which don't have a single entry point this presents a greater possibility to run into "Call to undefined function" errors. Supporting class instance or static methods will alleviate the issue by relying on the dynamic class autoloader.

Compatibility with PHPUnit 9

Currently the latest tagged version is not compatible with PHPUnit 9.

I've seen 466d043 that fixes this. When can we expect the next release to be tagged? Thanks for the great package.

Custom log providers

Idea

Add configuration option to retrieve log data from a custom log provider. This would give more flexibility to the user how logs are retrieved.

Right now the only way to pass log data from the logger to the analyzer is the "analyzer log format", which is files written to disk. If you want to run the analyzer, either you have to do it on the machine where the log files are located or you need to collect all the log files from those machines. So maybe you want to store logs differently, e.g. write them to a database or push them into some logging infrastructure and then retrieve the data from there.

If this idea would be useful to you, give it a +1

Report Generation for krakjoe/tombs

Idea

tombs by @krakjoe is an alternative implementation of the tombstone concept, which doesn't require to place tombstone calls in the code. Instead, it's an extension to the PHP runtime, which keeps track of called functions/methods and outputs log data for each call.

The log data could be used to generate reports with tombstone-analyzer. It would be necessary to add another tombstone extractor, which generates a "virtual tombstone" for each function/method in the codebase. This, combined with the logs from tombs, would generate a dead code report for the entire codebase.

If this idea would be useful to you, give it a +1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.