* com.noccy.watcher: Initial inotify support * ScriptRunner now accepts an array of local vars for expansion when evaluating scripts
		
			
				
	
	
		
			98 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			98 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
namespace SparkPlug\Com\Noccy\Watcher\Monitor;
 | 
						|
 | 
						|
use SparkPlug\Com\Noccy\Watcher\Rule;
 | 
						|
 | 
						|
class InotifyMonitor implements MonitorInterface
 | 
						|
{
 | 
						|
    private array $rules = [];
 | 
						|
 | 
						|
    private array $watched = [];
 | 
						|
 | 
						|
    private array $modified = [];
 | 
						|
 | 
						|
    private $fd;
 | 
						|
 | 
						|
    public function __construct()
 | 
						|
    {
 | 
						|
        $this->fd = \inotify_init();   
 | 
						|
    }
 | 
						|
 | 
						|
    public function __destruct()
 | 
						|
    {
 | 
						|
        if (is_resource($this->fd)) fclose($this->fd);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * {@inheritDoc}
 | 
						|
     */
 | 
						|
    public function add(Rule $rule)
 | 
						|
    {
 | 
						|
        $this->rules[] = $rule;
 | 
						|
 | 
						|
        $paths = $rule->getWatchedFiles();
 | 
						|
        $check = [];
 | 
						|
        foreach ($paths as $path) {
 | 
						|
            if (str_contains($path, '*')) {
 | 
						|
                $check = array_merge($check, glob($path));
 | 
						|
            } else {
 | 
						|
                $check[] = $path;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        $dirs = [];
 | 
						|
        foreach ($check as $path) {
 | 
						|
            $dir = is_dir($path) ? $path : dirname($path);
 | 
						|
            if (!array_key_exists($dir, $dirs)) {
 | 
						|
                $dirs[$dir] = $rule;
 | 
						|
                \inotify_add_watch($this->fd, $dir, \IN_ATTRIB);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        $this->watched = array_merge($this->watched, $dirs);
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * {@inheritDoc}
 | 
						|
     */
 | 
						|
    public function getModified(): array
 | 
						|
    {
 | 
						|
        $mod = $this->modified;
 | 
						|
        $this->modified = [];
 | 
						|
        return $mod;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * {@inheritDoc}
 | 
						|
     */
 | 
						|
    public function getWatched(): array
 | 
						|
    {
 | 
						|
        return [];        
 | 
						|
    }
 | 
						|
 | 
						|
    public function loop()
 | 
						|
    {
 | 
						|
        $read = [ $this->fd ];
 | 
						|
        $write = null;
 | 
						|
        $except = null;
 | 
						|
        $changed = [];
 | 
						|
        while (stream_select($read,$write,$except,0)) {
 | 
						|
            $events = \inotify_read($this->fd);
 | 
						|
            foreach ($events as $event) {
 | 
						|
                $changed[] = $event['name'];
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        foreach ($changed as $file) {
 | 
						|
            foreach ($this->watched as $dir=>$rule) {
 | 
						|
                if (file_exists($dir."/".$file)) {
 | 
						|
                    if (!in_array($rule, $this->modified)) {
 | 
						|
                        printf("~ modified: %s (%s)\n", $dir."/".$file, $rule->getName());
 | 
						|
                        $this->modified[] = $rule;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |