cakephp-ide-helper icon indicating copy to clipboard operation
cakephp-ide-helper copied to clipboard

Add a filesystem "watch" mode to regenerate the annotations on file changes

Open steinkel opened this issue 5 years ago • 1 comments

  • I'd like to have something like

bin/cake IdeHelper.watchAndRebuild --annotations --phpstorm

It'll start watching folders ./src ./plugins ./tests and re-run the annotations and phpstorm tasks when a file is changed.

steinkel avatar Jun 18 '20 13:06 steinkel

Do you have an idea on how to make this possible @steinkel ?

dereuromark avatar Jun 27 '24 11:06 dereuromark

Maybe https://github.com/dereuromark/cakephp-ide-helper/pull/386 is a first step? We could add a watcher system now that can call the helper with those files?

dereuromark avatar May 12 '25 11:05 dereuromark

Do you have a specific setup in mind?

For Cross OS sth slow like this could work?

    while (true) {
        sleep($this->interval);

        $currentSnapshot = $this->getFileSnapshot($watchDir);
        $changedFiles = $this->detectChanges($lastSnapshot, $currentSnapshot);

If we want to make more performent solutions for linux, we could look into

    while (true) {
        $events = inotify_read($inotify);
        if ($events) {
            $changedFiles = [];
            foreach ($events as $event) {
                $changedFiles[] = $event['name'];
            }

            //TODO
        }

        sleep($this->interval);
    }

or even

fswatch -o src/ | xargs -n1 -I{} bin/cake annotate ...

?

dereuromark avatar May 12 '25 12:05 dereuromark

"Node + Chokidar + CakePHP Integration" could also be an option:

node watcher.js
// watcher.js
const chokidar = require('chokidar');
const { exec } = require('child_process');

// Directory to watch
const watchPath = './src';

console.log(`🔍 Watching for file changes in ${watchPath}...`);

// Initialize watcher
chokidar.watch(watchPath, {
  ignored: /(^|[\/\\])\../, // ignore dotfiles
  persistent: true,
})
.on('change', path => {
  console.log(`📝 File changed: ${path}`);

  // Run CakePHP command
  exec('bin/cake handle_changes', (error, stdout, stderr) => {
    if (error) {
      console.error(`❌ Error executing CakePHP command: ${error.message}`);
      return;
    }
    if (stderr) {
      console.error(`⚠️ STDERR: ${stderr}`);
    }
    console.log(`✅ Output:\n${stdout}`);
  });
});

that should be fairly cross OS?

dereuromark avatar May 12 '25 12:05 dereuromark

Yes, that could work even if having an extra nodejs dependency is not great. Handling each OS separately would be painful for sure, inotify_read is OK, but reading files recursively to check for changes would be possibly a bad idea...

steinkel avatar May 12 '25 12:05 steinkel

In the case of the nodejs approach, it would not be a fix done to the plugin itself, but documentation on how you could do it to automate the generation of the annotations while you are working on the code. We would need to test this approach and ensure the annotation generation would not overwrite the entire file, or you could lost the latest edits you are working on if your IDE is not quick saving the file...

steinkel avatar May 12 '25 12:05 steinkel

Any help would be greatly appreciated.

dereuromark avatar May 12 '25 12:05 dereuromark

I'll try the "Node + Chokidar + CakePHP Integration" locally and get back to you. Thank you!

steinkel avatar May 12 '25 12:05 steinkel

Make sure to use dev-master to be able to use the --file functionality

dereuromark avatar May 13 '25 12:05 dereuromark

I've been checking a couple options...

I like this one https://github.com/watchexec/watchexec cross platform, plenty of options, 1 executable to download.

It worked pretty well using

$ watchexec -e php 'bin/cake annotate all'

From your root folder.

steinkel avatar May 15 '25 12:05 steinkel

Also https://github.com/dereuromark/cakephp-ide-helper/commit/a2442053149247bef3a257fdde0d8a5b47deabcb should help to further reduce the IO sync issues by not writing the same content if not necessary.

Especially on watcher invoked runs this should minimize the side effects.

$ watchexec -e php 'bin/cake annotate all'

Does this automatically append --file ... then or how does it work?

dereuromark avatar May 15 '25 12:05 dereuromark

It triggers on any change, recursively, from the indicated folder, the -e is to filter only changes in PHP files. Checking the command man page, --no-meta and -p would be good default options. I didn't see a way to print the changes or pass the list of changed files to the underlying command to reduce the io overhead. It works well for my use case.

steinkel avatar May 15 '25 13:05 steinkel

I see - you mean that "all" is fine enough and the overhead is not too much compared to a specific file run?

dereuromark avatar May 15 '25 13:05 dereuromark

I couldnt get the watchexec to get installed on my linux mint none of the normal channels worked.

But since for me the other solution works, I guess fair enough for now.

dereuromark avatar May 15 '25 15:05 dereuromark

Yes, I think the issue can be closed, we can leave a comment in the docs in case others are looking for this behavior. Thank you!

steinkel avatar May 15 '25 16:05 steinkel