Skip to content

Commit e08afc9

Browse files
committed
feat: run command
These steps make possible run occ and bash commands as steps. Signed-off-by: Vitor Mattos <[email protected]>
1 parent a796a67 commit e08afc9

File tree

3 files changed

+110
-0
lines changed

3 files changed

+110
-0
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ vendor/bin/behat -dl
5151
When as user :user
5252
When user :user exists
5353
When sending :verb to :url
54+
When set the response to:
5455
When the response should be a JSON array with the following mandatory values
5556
When /^set the display name of user "([^"]*)" to "([^"]*)"$/
5657
When /^set the email of user "([^"]*)" to "([^"]*)"$/
@@ -60,6 +61,9 @@ When fetch field :path from prevous JSON response
6061
When the response should contain the initial state :name with the following values:
6162
When the response should contain the initial state :name json that match with:
6263
When the following :appId app config is set
64+
When /^run the command "(?P<command>(?:[^"]|\\")*)"$/
65+
When /^run the command "(?P<command>(?:[^"]|\\")*)" with result code (\d+)$/
66+
When /^run the bash command "(?P<command>(?:[^"]|\\")*)" with result code (\d+)$/
6367
```
6468

6569
## Tips
@@ -83,6 +87,15 @@ When sending "post" to ocs "/apps/libresign/api/v1/request-signature"
8387
| file | {"base64":""} |
8488
```
8589

90+
### Step: all steps that run commands
91+
92+
Before the command be executd, will replace the follow placeholders:
93+
94+
| Placeholder | Value |
95+
| -------------------- | ---------------------- |
96+
| `<appRootDir>` | your app root dir |
97+
| `<nextcloudRootDir>` | The Nextcloud root dir |
98+
8699
### Step: `fetch field :path from prevous JSON response`
87100

88101
If the json response is an array, you can fetch specific values using this step. The fetched values is stored to be used by other steps.

features/test.feature

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,3 +207,21 @@ Feature: Test this extension
207207
Then the response should contain the initial state "appid-json-array" json that match with:
208208
| key | value |
209209
| (jq).[0] | orange |
210+
211+
Scenario: Test list app directory with success
212+
When run the bash command "ls <appRootDir>" with result code 0
213+
214+
Scenario: Test list Nextcloud directory with success
215+
When run the bash command "ls <nextcloudRootDir>" with result code 0
216+
217+
Scenario: Test run bash command with success
218+
When run the bash command "true" with result code 0
219+
220+
Scenario: Test run bash command with error
221+
When run the bash command "false" with result code 1
222+
223+
Scenario: Run occ command with success
224+
When run the command "status" with result code 0
225+
226+
Scenario: Run occ command with success
227+
When run the command "invalid-command" with result code 1

src/NextcloudApiContext.php

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,85 @@ protected function parseText(string $text): string {
462462
return $text;
463463
}
464464

465+
/**
466+
* @When /^run the command "(?P<command>(?:[^"]|\\")*)"$/
467+
*/
468+
public static function runCommand(string $command): array {
469+
$console = self::findParentDirContainingFile('console.php');
470+
$console .= '/console.php';
471+
$fileOwnerUid = fileowner($console);
472+
if (!is_int($fileOwnerUid)) {
473+
throw new \Exception('The console file owner of ' . $console . ' is not an integer UID.');
474+
}
475+
$owner = posix_getpwuid($fileOwnerUid);
476+
if ($owner === false) {
477+
throw new \Exception('Could not retrieve owner information for UID ' . $fileOwnerUid);
478+
}
479+
$fullCommand = 'php ' . $console . ' ' . $command;
480+
if (posix_getuid() !== $owner['uid']) {
481+
$fullCommand = 'runuser -u ' . $owner['name'] . ' -- ' . $fullCommand;
482+
}
483+
$fullCommand .= ' 2>&1';
484+
return self::runBashCommand($fullCommand);
485+
}
486+
487+
public static function findParentDirContainingFile(string $filename): string {
488+
$dir = getcwd();
489+
if (is_bool($dir)) {
490+
throw new \Exception('Could not get current working directory (getcwd() returned false)');
491+
}
492+
493+
while ($dir !== dirname($dir)) {
494+
if (file_exists($dir . DIRECTORY_SEPARATOR . $filename)) {
495+
return $dir;
496+
}
497+
$dir = dirname($dir);
498+
}
499+
500+
throw new \Exception('The file ' . $filename . ' was not found in the parent directories of ' . $dir);
501+
}
502+
503+
private static function runBashCommand(string $command): array {
504+
$command = str_replace('\"', '"', $command);
505+
$patterns = [];
506+
$replacements = [];
507+
$fields = [
508+
'appRootDir' => self::findParentDirContainingFile('appinfo'),
509+
'nextcloudRootDir' => self::findParentDirContainingFile('console.php'),
510+
];
511+
foreach ($fields as $key => $value) {
512+
$patterns[] = '/<' . $key . '>/';
513+
$replacements[] = $value;
514+
}
515+
$command = preg_replace($patterns, $replacements, $command);
516+
if (!is_string($command)) {
517+
throw new \Exception('The command is not a string after preg_replace: ' . print_r($command, true));
518+
}
519+
520+
exec($command, $output, $resultCode);
521+
return [
522+
'command' => $command,
523+
'output' => $output,
524+
'resultCode' => $resultCode,
525+
];
526+
}
527+
528+
/**
529+
* @When /^run the command "(?P<command>(?:[^"]|\\")*)" with result code (\d+)$/
530+
*/
531+
public static function runCommandWithResultCode(string $command, int $resultCode = 0): void {
532+
$return = self::runCommand($command);
533+
Assert::assertEquals($resultCode, $return['resultCode'], print_r($return, true));
534+
}
535+
536+
/**
537+
* @When /^run the bash command "(?P<command>(?:[^"]|\\")*)" with result code (\d+)$/
538+
*/
539+
public static function runBashCommandWithResultCode(string $command, int $resultCode = 0): void {
540+
$return = self::runBashCommand($command);
541+
Assert::assertEquals($resultCode, $return['resultCode'], print_r($return, true));
542+
}
543+
465544
/**
466545
* @AfterScenario
467546
*/

0 commit comments

Comments
 (0)