@@ -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