Skip to content

Commit

Permalink
fix: process attribute handling & tiny code-style refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
maximgrynykha committed May 18, 2024
1 parent 5b3a885 commit d6910f2
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 64 deletions.
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,15 @@ try {
```

### API (based on 'tasklist' command)
| Attribute name | Attribute value | Example | Compare operator |
|:------------------|:--------------------------------|:-----------------------|:------------------------------------------|
| `process_name` | [string]: simple name | chrome / figma | [string]: `=`, `!=` |
| | [string]: name with .ext | chrome.exe / figma.exe | [string]: `=`, `!=` |
| | [string]: uppercase name | Chrome.exe / Figma.exe | [string]: `=`, `!=` |
| `process_id` | [int]: number of the ID | | [string]: `=`, `!=` |
| `session_name` | [string]: Console / Services | | [string]: `=`, `!=` |
| `session_number` | [int]: number in range of {0-1} | | [string]: `=`, `!=` |
| `consumed_memory` | [int]: number in Kb(kilobytes) | | [string]: `>`, `<`, `=`, `>=`, `<=`, `!=` |
| Attribute name | Attribute value | Example | Compare operator |
|:------------------|:--------------------------------|:-----------|:------------------------------------------|
| `process_name` | [string]: name with ext | chrome.exe | [string]: `=`, `!=` |
| | [string]: name | chrome | [string]: `=`, `!=` |
| | [string]: ext | .exe | [string]: `=`, `!=` |
| `process_id` | [int]: number of the ID | | [string]: `=`, `!=` |
| `session_name` | [string]: Console / Services | | [string]: `=`, `!=` |
| `session_number` | [int]: number in range of {0-1} | | [string]: `=`, `!=` |
| `consumed_memory` | [int]: number in Kb (kilobytes) | | [string]: `>`, `<`, `=`, `>=`, `<=`, `!=` |

### Select processes

Expand Down
21 changes: 21 additions & 0 deletions src/Winkill/Kernel/Exception/UnsupportedAttributeValue.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace Winkill\Kernel\Exception;

use Winkill\Kernel\Interface\Exception;

final class UnsupportedAttributeValue extends \InvalidArgumentException implements Exception
{
/**
* @param string $attribute
* @param int|string $value
*
* @return self
*/
public static function from(string $attribute, int|string $value): self
{
return new self("Unsupported value: $value, for process attribute: $attribute.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,11 @@ public function parse(string $process): Process
$attribute = trim($attribute);
}

$memo = $attributes['consumed_memory'];

$attributes['process_id'] = (int)$attributes['process_id'];
$attributes['session_number'] = (int)$attributes['session_number'];

$attributes['consumed_memory'] = (int)preg_replace(
pattern: '/\D/',
replacement: '',
subject: $attributes['consumed_memory']
);
$attributes['consumed_memory'] = (int)preg_replace('/\D/', '', $memo);

return new WindowsProcess(...$attributes);
}
Expand Down
84 changes: 40 additions & 44 deletions src/Winkill/Kernel/OS/Windows/WindowsProcess.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Winkill\Kernel\Exception\UnsupportedAttributeComparisonOperator;
use Winkill\Kernel\Exception\NonexistentProcessAttribute;
use Winkill\Kernel\Exception\UnsupportedAttributeValue;
use Winkill\Kernel\Interface\Process;
use Winkill\Kernel\OS\Common\Comparison;

Expand Down Expand Up @@ -35,6 +36,14 @@ public function __construct(
$this->session_name = mb_strtolower(trim($session_name));
}

/**
* @return string
*/
public function __toString(): string
{
return json_encode($this, JSON_PRETTY_PRINT);
}

/**
* @param string $attribute
* @param string $compareAs
Expand All @@ -47,75 +56,62 @@ public function handleAttribute(
string $compareAs,
int|string $value
): bool {
$attribute = trim($attribute);
$compareAs = trim($compareAs);
$attribute = mb_strtolower(trim($attribute));
$compareAs = mb_strtolower(trim($compareAs));
$value = mb_strtolower(trim((string)$value));

switch ($attribute) {
case 'process_name':
if (!in_array($c = Comparison::tryFrom($compareAs), [Comparison::EQUAL, Comparison::NOT_EQUAL])) {
throw UnsupportedAttributeComparisonOperator::from($attribute, $compareAs);
}
$value = mb_strtolower(trim((string)$value));
return $this->handleProcessName($value, $c);

// chrome.exe
if (preg_match('/^\w+(\.\w+)+$/', $value)) {
return $c->compare($this->process_name, $value); # by_name+by_ext (full match)
}
// chrome
if (preg_match('/^[^.]*$/', $value)) {
return $c->compare(mb_strstr($this->process_name, '.', true), $value); # by_name
}
// .exe
if (preg_match('/^\./', $value)) {
return $c->compare(mb_strstr($this->process_name, '.', false), $value); # by_ext
}

return $c->compare($this->process_name, $value);
case 'process_id':
if (!in_array($c = Comparison::tryFrom($compareAs), [Comparison::EQUAL, Comparison::NOT_EQUAL])) {
throw UnsupportedAttributeComparisonOperator::from($attribute, $compareAs);
}
return $c->compare($this->process_id, +$value);

return $c->compare($this->process_id, (int)$value);
case 'session_name':
if (!in_array($c = Comparison::tryFrom($compareAs), [Comparison::EQUAL, Comparison::NOT_EQUAL])) {
throw UnsupportedAttributeComparisonOperator::from($attribute, $compareAs);
}
$value = mb_strtolower(trim((string)$value));
if (!in_array($value, ['console', 'services'])) {
throw UnsupportedAttributeValue::from($attribute, $value);
}

return $c->compare($this->session_name, $value);
case 'session_number':
if (!in_array($c = Comparison::tryFrom($compareAs), [Comparison::EQUAL, Comparison::NOT_EQUAL])) {
throw UnsupportedAttributeComparisonOperator::from($attribute, $compareAs);
}
return $c->compare($this->session_number, +$value);
if (!in_array($value, [0, 1])) {
throw UnsupportedAttributeValue::from($attribute, $value);
}

return $c->compare($this->session_number, (int)$value);
case 'consumed_memory':
if (!in_array($c = Comparison::tryFrom($compareAs), Comparison::values())) {
throw UnsupportedAttributeComparisonOperator::from($attribute, $compareAs);
}
return $c->compare($this->consumed_memory, +$value);

return $c->compare($this->consumed_memory, (int)$value);
default:
throw new NonexistentProcessAttribute($attribute);
}
}

/**
* @param string $process_name
* @param Comparison $comparison
*
* @return bool
*/
private function handleProcessName(string $process_name, Comparison $comparison): bool
{
$is_handled = $comparison->compare($this->process_name, $process_name);

if (str_contains($process_name, '.') || str_contains($this->process_name, '.')) {
$process_name_segments_in_argument = explode('.', $process_name);
$process_name_segments_in_instance = explode('.', $this->process_name);

$diff = array_diff(
$process_name_segments_in_argument,
$process_name_segments_in_instance
);

$is_handled = match ($comparison) {
Comparison::EQUAL => empty($diff),
Comparison::NOT_EQUAL => !empty($diff),
};
}

return $is_handled;
}

/**
* @return string
*/
public function __toString(): string
{
return json_encode($this, JSON_PRETTY_PRINT);
}
}
6 changes: 3 additions & 3 deletions src/Winkill/Kernel/Processes.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,9 @@ public function get(): array
* attribute: 'process_name',
* compareAs: '=',
* value: 'chrome' # You can pass the process name in the following formats:
* # [string]: simple name (chrome)
* # [string]: name with .ext (chrome.exe)
* # [string]: uppercase name (Chrome.exe)
* # [string]: name with ext (chrome.exe)
* # [string]: name (chrome)
* # [string]: ext (.exe)
* );
* ```
*
Expand Down
6 changes: 4 additions & 2 deletions src/Winkill/Winkill.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,13 @@ public function __construct(
public function scan(): Processes
{
$factory = match (PHP_OS_FAMILY) {
'Windows' => new CachingConfiguration(new WindowsConfiguration()),
'Windows' => new WindowsConfiguration(),
'Unknown' => throw new UnknownOperatingSystem(),
default => throw new UnsupportedOperatingSystem()
};

return new Processes($this->factory ?: $factory);
return new Processes(
new CachingConfiguration($this->factory ?: $factory)
);
}
}

0 comments on commit d6910f2

Please sign in to comment.