diff --git a/.github/workflows/appstore-build-publish.yml b/.github/workflows/appstore-build-publish.yml
index 338a567f..b468cee5 100644
--- a/.github/workflows/appstore-build-publish.yml
+++ b/.github/workflows/appstore-build-publish.yml
@@ -23,7 +23,7 @@ jobs:
if: ${{ github.repository_owner == 'nextcloud-releases' }}
steps:
- - uses: cachix/install-nix-action@02a151ada4993995686f9ed4f1be7cfbb229e56f # v31
+ - uses: cachix/install-nix-action@fc6e360bedc9ee72d75e701397f0bb30dce77568 # v31.5.2
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
with:
name: notify-push
@@ -41,7 +41,7 @@ jobs:
echo "APP_VERSION=${GITHUB_REF##*/}" >> $GITHUB_ENV
- name: Checkout
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
path: ${{ env.APP_NAME }}
@@ -49,7 +49,7 @@ jobs:
- name: Get app version number
id: app-version
- uses: skjnldsv/xpath-action@f5b036e9d973f42c86324833fd00be90665fbf77 # master
+ uses: skjnldsv/xpath-action@f5b036e9d973f42c86324833fd00be90665fbf77 # v1.0.0
with:
filename: ${{ env.APP_NAME }}/appinfo/info.xml
expression: "//info//version/text()"
@@ -60,7 +60,7 @@ jobs:
- name: Get appinfo data
id: appinfo
- uses: skjnldsv/xpath-action@f5b036e9d973f42c86324833fd00be90665fbf77 # master
+ uses: skjnldsv/xpath-action@f5b036e9d973f42c86324833fd00be90665fbf77 # v1.0.0
with:
filename: ${{ env.APP_NAME }}/appinfo/info.xml
expression: "//info//dependencies//nextcloud/@min-version"
@@ -78,7 +78,7 @@ jobs:
- name: Set up node ${{ steps.versions.outputs.nodeVersion }}
# Skip if no package.json
if: ${{ steps.versions.outputs.nodeVersion }}
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: ${{ steps.versions.outputs.nodeVersion }}
@@ -94,7 +94,7 @@ jobs:
filename: ${{ env.APP_NAME }}/appinfo/info.xml
- name: Set up php ${{ steps.php-versions.outputs.php-min }}
- uses: shivammathur/setup-php@9e72090525849c5e82e596468b86eb55e9cc5401 # v2.32.0
+ uses: shivammathur/setup-php@ccf2c627fe61b1b4d924adfcbd19d661a18133a0 # v2.35.2
with:
php-version: ${{ steps.php-versions.outputs.php-min }}
coverage: none
@@ -156,7 +156,7 @@ jobs:
unzip latest-$NCVERSION.zip
- name: Checkout server master fallback
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
if: ${{ steps.server-checkout.outcome != 'success' }}
with:
persist-credentials: false
@@ -180,7 +180,7 @@ jobs:
tar -zcvf ${{ env.APP_NAME }}.tar.gz ${{ env.APP_NAME }}
- name: Attach tarball to github release
- uses: svenstaro/upload-release-action@04733e069f2d7f7f0b4aebc4fbdbce8613b03ccd # v2
+ uses: svenstaro/upload-release-action@81c65b7cd4de9b2570615ce3aad67a41de5b1a13 # v2.11.2
id: attach_to_release
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
@@ -190,7 +190,7 @@ jobs:
overwrite: true
- name: Upload app to Nextcloud appstore
- uses: nextcloud-releases/nextcloud-appstore-push-action@a011fe619bcf6e77ddebc96f9908e1af4071b9c1 # v1
+ uses: nextcloud-releases/nextcloud-appstore-push-action@a011fe619bcf6e77ddebc96f9908e1af4071b9c1 # v1.0.3
with:
app_name: ${{ env.APP_NAME }}
appstore_token: ${{ secrets.APPSTORE_TOKEN }}
diff --git a/.github/workflows/appstore-build-publish.yml.patch b/.github/workflows/appstore-build-publish.yml.patch
index cead0770..5915354f 100644
--- a/.github/workflows/appstore-build-publish.yml.patch
+++ b/.github/workflows/appstore-build-publish.yml.patch
@@ -6,7 +6,7 @@ index 316ba14..3cb9983 100644
if: ${{ github.repository_owner == 'nextcloud-releases' }}
steps:
-+ - uses: cachix/install-nix-action@02a151ada4993995686f9ed4f1be7cfbb229e56f # v31
++ - uses: cachix/install-nix-action@fc6e360bedc9ee72d75e701397f0bb30dce77568 # v31.5.2
+ - uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
+ with:
+ name: notify-push
diff --git a/.github/workflows/lint-info-xml.yml b/.github/workflows/lint-info-xml.yml
index 25b65504..78610590 100644
--- a/.github/workflows/lint-info-xml.yml
+++ b/.github/workflows/lint-info-xml.yml
@@ -24,7 +24,7 @@ jobs:
name: info.xml lint
steps:
- name: Checkout
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
diff --git a/.github/workflows/lint-php-cs.yml b/.github/workflows/lint-php-cs.yml
index 681ecca6..b2d8b7b2 100644
--- a/.github/workflows/lint-php-cs.yml
+++ b/.github/workflows/lint-php-cs.yml
@@ -25,7 +25,7 @@ jobs:
steps:
- name: Checkout
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
@@ -34,7 +34,7 @@ jobs:
uses: icewind1991/nextcloud-version-matrix@58becf3b4bb6dc6cef677b15e2fd8e7d48c0908f # v1.3.1
- name: Set up php${{ steps.versions.outputs.php-min }}
- uses: shivammathur/setup-php@9e72090525849c5e82e596468b86eb55e9cc5401 # v2.32.0
+ uses: shivammathur/setup-php@ccf2c627fe61b1b4d924adfcbd19d661a18133a0 # v2.35.2
with:
php-version: ${{ steps.versions.outputs.php-min }}
extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite
@@ -45,7 +45,7 @@ jobs:
- name: Install dependencies
run: |
- composer remove nextcloud/ocp --dev
+ composer remove nextcloud/ocp --dev --no-scripts
composer i
- name: Lint
diff --git a/.github/workflows/lint-php.yml b/.github/workflows/lint-php.yml
index cdb2ba45..119aa32a 100644
--- a/.github/workflows/lint-php.yml
+++ b/.github/workflows/lint-php.yml
@@ -24,7 +24,7 @@ jobs:
php-versions: ${{ steps.versions.outputs.php-versions }}
steps:
- name: Checkout app
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
@@ -43,12 +43,12 @@ jobs:
steps:
- name: Checkout
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Set up php ${{ matrix.php-versions }}
- uses: shivammathur/setup-php@9e72090525849c5e82e596468b86eb55e9cc5401 # v2.32.0
+ uses: shivammathur/setup-php@ccf2c627fe61b1b4d924adfcbd19d661a18133a0 # v2.35.2
with:
php-version: ${{ matrix.php-versions }}
extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite
diff --git a/.github/workflows/phpunit-mysql.yml b/.github/workflows/phpunit-mysql.yml
deleted file mode 100644
index c53d2984..00000000
--- a/.github/workflows/phpunit-mysql.yml
+++ /dev/null
@@ -1,200 +0,0 @@
-# This workflow is provided via the organization template repository
-#
-# https://github.com/nextcloud/.github
-# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
-#
-# SPDX-FileCopyrightText: 2022-2024 Nextcloud GmbH and Nextcloud contributors
-# SPDX-License-Identifier: MIT
-
-name: PHPUnit MySQL
-
-on: pull_request
-
-permissions:
- contents: read
-
-concurrency:
- group: phpunit-mysql-${{ github.head_ref || github.run_id }}
- cancel-in-progress: true
-
-jobs:
- matrix:
- runs-on: ubuntu-latest-low
- outputs:
- matrix: ${{ steps.versions.outputs.sparse-matrix }}
- steps:
- - name: Checkout app
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- with:
- persist-credentials: false
-
- - name: Get version matrix
- id: versions
- uses: icewind1991/nextcloud-version-matrix@58becf3b4bb6dc6cef677b15e2fd8e7d48c0908f # v1.3.1
- with:
- matrix: '{"mysql-versions": ["8.4"]}'
-
- changes:
- runs-on: ubuntu-latest-low
- permissions:
- contents: read
- pull-requests: read
-
- outputs:
- src: ${{ steps.changes.outputs.src}}
-
- steps:
- - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
- id: changes
- continue-on-error: true
- with:
- filters: |
- src:
- - '.github/workflows/**'
- - 'appinfo/**'
- - 'lib/**'
- - 'templates/**'
- - 'tests/**'
- - 'vendor/**'
- - 'vendor-bin/**'
- - '.php-cs-fixer.dist.php'
- - 'composer.json'
- - 'composer.lock'
-
- phpunit-mysql:
- runs-on: ubuntu-latest
-
- needs: [changes, matrix]
- if: needs.changes.outputs.src != 'false'
-
- strategy:
- matrix: ${{ fromJson(needs.matrix.outputs.matrix) }}
-
- name: MySQL ${{ matrix.mysql-versions }} PHP ${{ matrix.php-versions }} Nextcloud ${{ matrix.server-versions }}
-
- services:
- mysql:
- image: ghcr.io/nextcloud/continuous-integration-mysql-${{ matrix.mysql-versions }}:latest
- ports:
- - 4444:3306/tcp
- env:
- MYSQL_ROOT_PASSWORD: rootpassword
- options: --health-cmd="mysqladmin ping" --health-interval 5s --health-timeout 2s --health-retries 10
-
- steps:
- - name: Set app env
- if: ${{ env.APP_NAME == '' }}
- run: |
- # Split and keep last
- echo "APP_NAME=${GITHUB_REPOSITORY##*/}" >> $GITHUB_ENV
-
- - name: Checkout server
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- with:
- persist-credentials: false
- submodules: true
- repository: nextcloud/server
- ref: ${{ matrix.server-versions }}
-
- - name: Checkout app
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- with:
- persist-credentials: false
- path: apps/${{ env.APP_NAME }}
-
- - name: Set up php ${{ matrix.php-versions }}
- uses: shivammathur/setup-php@9e72090525849c5e82e596468b86eb55e9cc5401 # v2.32.0
- with:
- php-version: ${{ matrix.php-versions }}
- # https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation
- extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, mysql, pdo_mysql
- coverage: none
- ini-file: development
- # Temporary workaround for missing pcntl_* in PHP 8.3
- ini-values: disable_functions=
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Enable ONLY_FULL_GROUP_BY MySQL option
- run: |
- echo "SET GLOBAL sql_mode=(SELECT CONCAT(@@sql_mode,',ONLY_FULL_GROUP_BY'));" | mysql -h 127.0.0.1 -P 4444 -u root -prootpassword
- echo 'SELECT @@sql_mode;' | mysql -h 127.0.0.1 -P 4444 -u root -prootpassword
-
- - name: Check composer file existence
- id: check_composer
- uses: andstor/file-existence-action@076e0072799f4942c8bc574a82233e1e4d13e9d6 # v3.0.0
- with:
- files: apps/${{ env.APP_NAME }}/composer.json
-
- - name: Set up dependencies
- # Only run if phpunit config file exists
- if: steps.check_composer.outputs.files_exists == 'true'
- working-directory: apps/${{ env.APP_NAME }}
- run: |
- composer remove nextcloud/ocp --dev
- composer i
-
- - name: Set up Nextcloud
- env:
- DB_PORT: 4444
- run: |
- mkdir data
- ./occ maintenance:install --verbose --database=mysql --database-name=nextcloud --database-host=127.0.0.1 --database-port=$DB_PORT --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass admin
- ./occ app:enable --force ${{ env.APP_NAME }}
-
- - name: Check PHPUnit script is defined
- id: check_phpunit
- continue-on-error: true
- working-directory: apps/${{ env.APP_NAME }}
- run: |
- composer run --list | grep '^ test:unit ' | wc -l | grep 1
-
- - name: PHPUnit
- # Only run if phpunit config file exists
- if: steps.check_phpunit.outcome == 'success'
- working-directory: apps/${{ env.APP_NAME }}
- run: composer run test:unit
-
- - name: Check PHPUnit integration script is defined
- id: check_integration
- continue-on-error: true
- working-directory: apps/${{ env.APP_NAME }}
- run: |
- composer run --list | grep '^ test:integration ' | wc -l | grep 1
-
- - name: Run Nextcloud
- # Only run if phpunit integration config file exists
- if: steps.check_integration.outcome == 'success'
- run: php -S localhost:8080 &
-
- - name: PHPUnit integration
- # Only run if phpunit integration config file exists
- if: steps.check_integration.outcome == 'success'
- working-directory: apps/${{ env.APP_NAME }}
- run: composer run test:integration
-
- - name: Print logs
- if: always()
- run: |
- cat data/nextcloud.log
-
- - name: Skipped
- # Fail the action when neither unit nor integration tests ran
- if: steps.check_phpunit.outcome == 'failure' && steps.check_integration.outcome == 'failure'
- run: |
- echo 'Neither PHPUnit nor PHPUnit integration tests are specified in composer.json scripts'
- exit 1
-
- summary:
- permissions:
- contents: none
- runs-on: ubuntu-latest-low
- needs: [changes, phpunit-mysql]
-
- if: always()
-
- name: phpunit-mysql-summary
-
- steps:
- - name: Summary status
- run: if ${{ needs.changes.outputs.src != 'false' && needs.phpunit-mysql.result != 'success' }}; then exit 1; fi
diff --git a/.github/workflows/phpunit-oci.yml b/.github/workflows/phpunit-oci.yml
deleted file mode 100644
index 743afb3a..00000000
--- a/.github/workflows/phpunit-oci.yml
+++ /dev/null
@@ -1,208 +0,0 @@
-# This workflow is provided via the organization template repository
-#
-# https://github.com/nextcloud/.github
-# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
-#
-# SPDX-FileCopyrightText: 2022-2024 Nextcloud GmbH and Nextcloud contributors
-# SPDX-License-Identifier: MIT
-
-name: PHPUnit OCI
-
-on: pull_request
-
-permissions:
- contents: read
-
-concurrency:
- group: phpunit-oci-${{ github.head_ref || github.run_id }}
- cancel-in-progress: true
-
-jobs:
- matrix:
- runs-on: ubuntu-latest-low
- outputs:
- php-version: ${{ steps.versions.outputs.php-available-list }}
- server-max: ${{ steps.versions.outputs.branches-max-list }}
- steps:
- - name: Checkout app
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- with:
- persist-credentials: false
-
- - name: Get version matrix
- id: versions
- uses: icewind1991/nextcloud-version-matrix@58becf3b4bb6dc6cef677b15e2fd8e7d48c0908f # v1.3.1
-
- changes:
- runs-on: ubuntu-latest-low
- permissions:
- contents: read
- pull-requests: read
-
- outputs:
- src: ${{ steps.changes.outputs.src }}
-
- steps:
- - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
- id: changes
- continue-on-error: true
- with:
- filters: |
- src:
- - '.github/workflows/**'
- - 'appinfo/**'
- - 'lib/**'
- - 'templates/**'
- - 'tests/**'
- - 'vendor/**'
- - 'vendor-bin/**'
- - '.php-cs-fixer.dist.php'
- - 'composer.json'
- - 'composer.lock'
-
- phpunit-oci:
- runs-on: ubuntu-latest
-
- needs: [changes, matrix]
- if: needs.changes.outputs.src != 'false'
-
- strategy:
- matrix:
- php-versions: ${{ fromJson(needs.matrix.outputs.php-version) }}
- server-versions: ${{ fromJson(needs.matrix.outputs.server-max) }}
-
- name: OCI PHP ${{ matrix.php-versions }} Nextcloud ${{ matrix.server-versions }}
-
- services:
- oracle:
- image: ghcr.io/gvenzl/oracle-xe:11
-
- # Provide passwords and other environment variables to container
- env:
- ORACLE_RANDOM_PASSWORD: true
- APP_USER: autotest
- APP_USER_PASSWORD: owncloud
-
- # Forward Oracle port
- ports:
- - 1521:1521/tcp
-
- # Provide healthcheck script options for startup
- options: >-
- --health-cmd healthcheck.sh
- --health-interval 10s
- --health-timeout 5s
- --health-retries 10
-
- steps:
- - name: Set app env
- if: ${{ env.APP_NAME == '' }}
- run: |
- # Split and keep last
- echo "APP_NAME=${GITHUB_REPOSITORY##*/}" >> $GITHUB_ENV
-
- - name: Checkout server
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- with:
- persist-credentials: false
- submodules: true
- repository: nextcloud/server
- ref: ${{ matrix.server-versions }}
-
- - name: Checkout app
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- with:
- persist-credentials: false
- path: apps/${{ env.APP_NAME }}
-
- - name: Set up php ${{ matrix.php-versions }}
- uses: shivammathur/setup-php@9e72090525849c5e82e596468b86eb55e9cc5401 # v2.32.0
- with:
- php-version: ${{ matrix.php-versions }}
- # https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation
- extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, oci8
- coverage: none
- ini-file: development
- # Temporary workaround for missing pcntl_* in PHP 8.3
- ini-values: disable_functions=
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Check composer file existence
- id: check_composer
- uses: andstor/file-existence-action@076e0072799f4942c8bc574a82233e1e4d13e9d6 # v3.0.0
- with:
- files: apps/${{ env.APP_NAME }}/composer.json
-
- - name: Set up dependencies
- # Only run if phpunit config file exists
- if: steps.check_composer.outputs.files_exists == 'true'
- working-directory: apps/${{ env.APP_NAME }}
- run: |
- composer remove nextcloud/ocp --dev
- composer i
-
- - name: Set up Nextcloud
- env:
- DB_PORT: 1521
- run: |
- mkdir data
- ./occ maintenance:install --verbose --database=oci --database-name=XE --database-host=127.0.0.1 --database-port=$DB_PORT --database-user=autotest --database-pass=owncloud --admin-user admin --admin-pass admin
- ./occ app:enable --force ${{ env.APP_NAME }}
-
- - name: Check PHPUnit script is defined
- id: check_phpunit
- continue-on-error: true
- working-directory: apps/${{ env.APP_NAME }}
- run: |
- composer run --list | grep '^ test:unit ' | wc -l | grep 1
-
- - name: PHPUnit
- # Only run if phpunit config file exists
- if: steps.check_phpunit.outcome == 'success'
- working-directory: apps/${{ env.APP_NAME }}
- run: composer run test:unit
-
- - name: Check PHPUnit integration script is defined
- id: check_integration
- continue-on-error: true
- working-directory: apps/${{ env.APP_NAME }}
- run: |
- composer run --list | grep '^ test:integration ' | wc -l | grep 1
-
- - name: Run Nextcloud
- # Only run if phpunit integration config file exists
- if: steps.check_integration.outcome == 'success'
- run: php -S localhost:8080 &
-
- - name: PHPUnit integration
- # Only run if phpunit integration config file exists
- if: steps.check_integration.outcome == 'success'
- working-directory: apps/${{ env.APP_NAME }}
- run: composer run test:integration
-
- - name: Print logs
- if: always()
- run: |
- cat data/nextcloud.log
-
- - name: Skipped
- # Fail the action when neither unit nor integration tests ran
- if: steps.check_phpunit.outcome == 'failure' && steps.check_integration.outcome == 'failure'
- run: |
- echo 'Neither PHPUnit nor PHPUnit integration tests are specified in composer.json scripts'
- exit 1
-
- summary:
- permissions:
- contents: none
- runs-on: ubuntu-latest-low
- needs: [changes, phpunit-oci]
-
- if: always()
-
- name: phpunit-oci-summary
-
- steps:
- - name: Summary status
- run: if ${{ needs.changes.outputs.src != 'false' && needs.phpunit-oci.result != 'success' }}; then exit 1; fi
diff --git a/.github/workflows/phpunit-pgsql.yml b/.github/workflows/phpunit-pgsql.yml
deleted file mode 100644
index 320dc19c..00000000
--- a/.github/workflows/phpunit-pgsql.yml
+++ /dev/null
@@ -1,198 +0,0 @@
-# This workflow is provided via the organization template repository
-#
-# https://github.com/nextcloud/.github
-# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
-#
-# SPDX-FileCopyrightText: 2022-2024 Nextcloud GmbH and Nextcloud contributors
-# SPDX-License-Identifier: MIT
-
-name: PHPUnit PostgreSQL
-
-on: pull_request
-
-permissions:
- contents: read
-
-concurrency:
- group: phpunit-pgsql-${{ github.head_ref || github.run_id }}
- cancel-in-progress: true
-
-jobs:
- matrix:
- runs-on: ubuntu-latest-low
- outputs:
- php-version: ${{ steps.versions.outputs.php-available-list }}
- server-max: ${{ steps.versions.outputs.branches-max-list }}
- steps:
- - name: Checkout app
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- with:
- persist-credentials: false
-
- - name: Get version matrix
- id: versions
- uses: icewind1991/nextcloud-version-matrix@58becf3b4bb6dc6cef677b15e2fd8e7d48c0908f # v1.3.1
-
- changes:
- runs-on: ubuntu-latest-low
- permissions:
- contents: read
- pull-requests: read
-
- outputs:
- src: ${{ steps.changes.outputs.src }}
-
- steps:
- - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
- id: changes
- continue-on-error: true
- with:
- filters: |
- src:
- - '.github/workflows/**'
- - 'appinfo/**'
- - 'lib/**'
- - 'templates/**'
- - 'tests/**'
- - 'vendor/**'
- - 'vendor-bin/**'
- - '.php-cs-fixer.dist.php'
- - 'composer.json'
- - 'composer.lock'
-
- phpunit-pgsql:
- runs-on: ubuntu-latest
-
- needs: [changes, matrix]
- if: needs.changes.outputs.src != 'false'
-
- strategy:
- matrix:
- php-versions: ${{ fromJson(needs.matrix.outputs.php-version) }}
- server-versions: ${{ fromJson(needs.matrix.outputs.server-max) }}
-
- name: PostgreSQL PHP ${{ matrix.php-versions }} Nextcloud ${{ matrix.server-versions }}
-
- services:
- postgres:
- image: ghcr.io/nextcloud/continuous-integration-postgres-14:latest
- ports:
- - 4444:5432/tcp
- env:
- POSTGRES_USER: root
- POSTGRES_PASSWORD: rootpassword
- POSTGRES_DB: nextcloud
- options: --health-cmd pg_isready --health-interval 5s --health-timeout 2s --health-retries 5
-
- steps:
- - name: Set app env
- if: ${{ env.APP_NAME == '' }}
- run: |
- # Split and keep last
- echo "APP_NAME=${GITHUB_REPOSITORY##*/}" >> $GITHUB_ENV
-
- - name: Checkout server
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- with:
- persist-credentials: false
- submodules: true
- repository: nextcloud/server
- ref: ${{ matrix.server-versions }}
-
- - name: Checkout app
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- with:
- persist-credentials: false
- path: apps/${{ env.APP_NAME }}
-
- - name: Set up php ${{ matrix.php-versions }}
- uses: shivammathur/setup-php@9e72090525849c5e82e596468b86eb55e9cc5401 # v2.32.0
- with:
- php-version: ${{ matrix.php-versions }}
- # https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation
- extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, pgsql, pdo_pgsql
- coverage: none
- ini-file: development
- # Temporary workaround for missing pcntl_* in PHP 8.3
- ini-values: disable_functions=
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Check composer file existence
- id: check_composer
- uses: andstor/file-existence-action@076e0072799f4942c8bc574a82233e1e4d13e9d6 # v3.0.0
- with:
- files: apps/${{ env.APP_NAME }}/composer.json
-
- - name: Set up dependencies
- # Only run if phpunit config file exists
- if: steps.check_composer.outputs.files_exists == 'true'
- working-directory: apps/${{ env.APP_NAME }}
- run: |
- composer remove nextcloud/ocp --dev
- composer i
-
- - name: Set up Nextcloud
- env:
- DB_PORT: 4444
- run: |
- mkdir data
- ./occ maintenance:install --verbose --database=pgsql --database-name=nextcloud --database-host=127.0.0.1 --database-port=$DB_PORT --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass admin
- ./occ app:enable --force ${{ env.APP_NAME }}
-
- - name: Check PHPUnit script is defined
- id: check_phpunit
- continue-on-error: true
- working-directory: apps/${{ env.APP_NAME }}
- run: |
- composer run --list | grep '^ test:unit ' | wc -l | grep 1
-
- - name: PHPUnit
- # Only run if phpunit config file exists
- if: steps.check_phpunit.outcome == 'success'
- working-directory: apps/${{ env.APP_NAME }}
- run: composer run test:unit
-
- - name: Check PHPUnit integration script is defined
- id: check_integration
- continue-on-error: true
- working-directory: apps/${{ env.APP_NAME }}
- run: |
- composer run --list | grep '^ test:integration ' | wc -l | grep 1
-
- - name: Run Nextcloud
- # Only run if phpunit integration config file exists
- if: steps.check_integration.outcome == 'success'
- run: php -S localhost:8080 &
-
- - name: PHPUnit integration
- # Only run if phpunit integration config file exists
- if: steps.check_integration.outcome == 'success'
- working-directory: apps/${{ env.APP_NAME }}
- run: composer run test:integration
-
- - name: Print logs
- if: always()
- run: |
- cat data/nextcloud.log
-
- - name: Skipped
- # Fail the action when neither unit nor integration tests ran
- if: steps.check_phpunit.outcome == 'failure' && steps.check_integration.outcome == 'failure'
- run: |
- echo 'Neither PHPUnit nor PHPUnit integration tests are specified in composer.json scripts'
- exit 1
-
- summary:
- permissions:
- contents: none
- runs-on: ubuntu-latest-low
- needs: [changes, phpunit-pgsql]
-
- if: always()
-
- name: phpunit-pgsql-summary
-
- steps:
- - name: Summary status
- run: if ${{ needs.changes.outputs.src != 'false' && needs.phpunit-pgsql.result != 'success' }}; then exit 1; fi
diff --git a/.github/workflows/phpunit-sqlite.yml b/.github/workflows/phpunit-sqlite.yml
index a61dc4cd..71b6c38b 100644
--- a/.github/workflows/phpunit-sqlite.yml
+++ b/.github/workflows/phpunit-sqlite.yml
@@ -25,7 +25,7 @@ jobs:
server-max: ${{ steps.versions.outputs.branches-max-list }}
steps:
- name: Checkout app
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
@@ -66,6 +66,17 @@ jobs:
needs: [changes, matrix]
if: needs.changes.outputs.src != 'false'
+ services:
+ redis:
+ image: redis
+ options: >-
+ --health-cmd "redis-cli ping"
+ --health-interval 10s
+ --health-timeout 5s
+ --health-retries 5
+ ports:
+ - 6379:6379
+
strategy:
matrix:
php-versions: ${{ fromJson(needs.matrix.outputs.php-version) }}
@@ -81,7 +92,7 @@ jobs:
echo "APP_NAME=${GITHUB_REPOSITORY##*/}" >> $GITHUB_ENV
- name: Checkout server
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
submodules: true
@@ -89,13 +100,13 @@ jobs:
ref: ${{ matrix.server-versions }}
- name: Checkout app
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
path: apps/${{ env.APP_NAME }}
- name: Set up php ${{ matrix.php-versions }}
- uses: shivammathur/setup-php@9e72090525849c5e82e596468b86eb55e9cc5401 # v2.32.0
+ uses: shivammathur/setup-php@ccf2c627fe61b1b4d924adfcbd19d661a18133a0 # v2.35.2
with:
php-version: ${{ matrix.php-versions }}
# https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation
@@ -118,7 +129,7 @@ jobs:
if: steps.check_composer.outputs.files_exists == 'true'
working-directory: apps/${{ env.APP_NAME }}
run: |
- composer remove nextcloud/ocp --dev
+ composer remove nextcloud/ocp --dev --no-scripts
composer i
- name: Set up Nextcloud
diff --git a/.github/workflows/pr-feedback.yml b/.github/workflows/pr-feedback.yml
index 98e9fada..f4c0477c 100644
--- a/.github/workflows/pr-feedback.yml
+++ b/.github/workflows/pr-feedback.yml
@@ -36,7 +36,7 @@ jobs:
blocklist=$(curl https://raw.githubusercontent.com/nextcloud/.github/master/non-community-usernames.txt | paste -s -d, -)
echo "blocklist=$blocklist" >> "$GITHUB_OUTPUT"
- - uses: nextcloud/pr-feedback-action@1883b38a033fb16f576875e0cf45f98b857655c4 # main
+ - uses: nextcloud/pr-feedback-action@f0cab224dea8e1f282f9451de322f323c78fc7a5 # main
with:
feedback-message: |
Hello there,
@@ -50,6 +50,6 @@ jobs:
(If you believe you should not receive this message, you can add yourself to the [blocklist](https://github.com/nextcloud/.github/blob/master/non-community-usernames.txt).)
days-before-feedback: 14
- start-date: '2024-04-30'
+ start-date: '2025-06-12'
exempt-authors: '${{ steps.blocklist.outputs.blocklist }},${{ steps.scrape.outputs.users }}'
exempt-bots: true
diff --git a/.github/workflows/psalm-matrix.yml b/.github/workflows/psalm-matrix.yml
index 033a6444..e0f19269 100644
--- a/.github/workflows/psalm-matrix.yml
+++ b/.github/workflows/psalm-matrix.yml
@@ -24,7 +24,7 @@ jobs:
ocp-matrix: ${{ steps.versions.outputs.ocp-matrix }}
steps:
- name: Checkout app
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
@@ -46,15 +46,15 @@ jobs:
name: static-psalm-analysis ${{ matrix.ocp-version }}
steps:
- name: Checkout
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- - name: Set up php${{ matrix.php-versions }}
- uses: shivammathur/setup-php@9e72090525849c5e82e596468b86eb55e9cc5401 # v2.32.0
+ - name: Set up php${{ matrix.php-min }}
+ uses: shivammathur/setup-php@ccf2c627fe61b1b4d924adfcbd19d661a18133a0 # v2.35.2
with:
- php-version: ${{ matrix.php-versions }}
- extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite
+ php-version: ${{ matrix.php-min }}
+ extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite, redis
coverage: none
ini-file: development
# Temporary workaround for missing pcntl_* in PHP 8.3
@@ -64,9 +64,11 @@ jobs:
- name: Install dependencies
run: |
- composer remove nextcloud/ocp --dev
+ composer remove nextcloud/ocp --dev --no-scripts
composer i
+ - name: Check for vulnerable PHP dependencies
+ run: composer require --dev roave/security-advisories:dev-latest
- name: Install dependencies # zizmor: ignore[template-injection]
run: composer require --dev 'nextcloud/ocp:${{ matrix.ocp-version }}' --ignore-platform-reqs --with-dependencies
diff --git a/.github/workflows/reuse.yml b/.github/workflows/reuse.yml
index 0d8e1962..ec4ad71c 100644
--- a/.github/workflows/reuse.yml
+++ b/.github/workflows/reuse.yml
@@ -16,10 +16,10 @@ permissions:
jobs:
reuse-compliance-check:
- runs-on: ubuntu-latest
+ runs-on: ubuntu-latest-low
steps:
- name: Checkout
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php
index 60bb945d..caa42ba7 100644
--- a/.php-cs-fixer.dist.php
+++ b/.php-cs-fixer.dist.php
@@ -15,6 +15,7 @@
->ignoreVCSIgnored(true)
->notPath('build')
->notPath('l10n')
+ ->notPath('tests/stubs')
->notPath('lib/Vendor')
->notPath('src')
->notPath('tests/configs')
diff --git a/REUSE.toml b/REUSE.toml
index bcd2cbd2..d76c9152 100644
--- a/REUSE.toml
+++ b/REUSE.toml
@@ -28,3 +28,9 @@ path = ["vendor-bin/**"]
precedence = "aggregate"
SPDX-FileCopyrightText = "2024 Nextcloud GmbH and Nextcloud contributors"
SPDX-License-Identifier = "AGPL-3.0-or-later"
+
+[[annotations]]
+path = ["tests/stubs/symfony_component_**"]
+precedence = "aggregate"
+SPDX-FileCopyrightText = "none"
+SPDX-License-Identifier = "MIT"
diff --git a/appinfo/info.xml b/appinfo/info.xml
index 521ee0d3..186eca25 100644
--- a/appinfo/info.xml
+++ b/appinfo/info.xml
@@ -11,7 +11,7 @@
- 1.1.1
+ 1.2.0
agpl
Robin Appelman
NotifyPush
@@ -27,7 +27,7 @@ Once the app is installed, the push binary needs to be setup. You can either use
https://github.com/nextcloud/notify_push/issues
-
+
diff --git a/psalm.xml b/psalm.xml
index 970727d4..55758e1b 100644
--- a/psalm.xml
+++ b/psalm.xml
@@ -21,5 +21,14 @@
+
+
+
+
+
+
+
+
+
diff --git a/tests/stubs/symfony_component_console_command_command.php b/tests/stubs/symfony_component_console_command_command.php
new file mode 100644
index 00000000..59094f71
--- /dev/null
+++ b/tests/stubs/symfony_component_console_command_command.php
@@ -0,0 +1,442 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Command;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Attribute\AsCommand;
+use Symfony\Component\Console\Completion\CompletionInput;
+use Symfony\Component\Console\Completion\CompletionSuggestions;
+use Symfony\Component\Console\Completion\Suggestion;
+use Symfony\Component\Console\Exception\ExceptionInterface;
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+use Symfony\Component\Console\Exception\LogicException;
+use Symfony\Component\Console\Helper\HelperInterface;
+use Symfony\Component\Console\Helper\HelperSet;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Base class for all commands.
+ *
+ * @author Fabien Potencier
+ */
+class Command
+{
+ // see https://tldp.org/LDP/abs/html/exitcodes.html
+ public const SUCCESS = 0;
+ public const FAILURE = 1;
+ public const INVALID = 2;
+
+ /**
+ * @var string|null The default command name
+ *
+ * @deprecated since Symfony 6.1, use the AsCommand attribute instead
+ */
+ protected static $defaultName;
+
+ /**
+ * @var string|null The default command description
+ *
+ * @deprecated since Symfony 6.1, use the AsCommand attribute instead
+ */
+ protected static $defaultDescription;
+
+ public static function getDefaultName(): ?string
+ {
+ }
+
+ public static function getDefaultDescription(): ?string
+ {
+ }
+
+ /**
+ * @param string|null $name The name of the command; passing null means it must be set in configure()
+ *
+ * @throws LogicException When the command name is empty
+ */
+ public function __construct(?string $name = null)
+ {
+ }
+
+ /**
+ * Ignores validation errors.
+ *
+ * This is mainly useful for the help command.
+ *
+ * @return void
+ */
+ public function ignoreValidationErrors()
+ {
+ }
+
+ /**
+ * @return void
+ */
+ public function setApplication(?Application $application = null)
+ {
+ }
+
+ /**
+ * @return void
+ */
+ public function setHelperSet(HelperSet $helperSet)
+ {
+ }
+
+ /**
+ * Gets the helper set.
+ */
+ public function getHelperSet(): ?HelperSet
+ {
+ }
+
+ /**
+ * Gets the application instance for this command.
+ */
+ public function getApplication(): ?Application
+ {
+ }
+
+ /**
+ * Checks whether the command is enabled or not in the current environment.
+ *
+ * Override this to check for x or y and return false if the command cannot
+ * run properly under the current conditions.
+ *
+ * @return bool
+ */
+ public function isEnabled()
+ {
+ }
+
+ /**
+ * Configures the current command.
+ *
+ * @return void
+ */
+ protected function configure()
+ {
+ }
+
+ /**
+ * Executes the current command.
+ *
+ * This method is not abstract because you can use this class
+ * as a concrete class. In this case, instead of defining the
+ * execute() method, you set the code to execute by passing
+ * a Closure to the setCode() method.
+ *
+ * @return int 0 if everything went fine, or an exit code
+ *
+ * @throws LogicException When this abstract method is not implemented
+ *
+ * @see setCode()
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ }
+
+ /**
+ * Interacts with the user.
+ *
+ * This method is executed before the InputDefinition is validated.
+ * This means that this is the only place where the command can
+ * interactively ask for values of missing required arguments.
+ *
+ * @return void
+ */
+ protected function interact(InputInterface $input, OutputInterface $output)
+ {
+ }
+
+ /**
+ * Initializes the command after the input has been bound and before the input
+ * is validated.
+ *
+ * This is mainly useful when a lot of commands extends one main command
+ * where some things need to be initialized based on the input arguments and options.
+ *
+ * @see InputInterface::bind()
+ * @see InputInterface::validate()
+ *
+ * @return void
+ */
+ protected function initialize(InputInterface $input, OutputInterface $output)
+ {
+ }
+
+ /**
+ * Runs the command.
+ *
+ * The code to execute is either defined directly with the
+ * setCode() method or by overriding the execute() method
+ * in a sub-class.
+ *
+ * @return int The command exit code
+ *
+ * @throws ExceptionInterface When input binding fails. Bypass this by calling {@link ignoreValidationErrors()}.
+ *
+ * @see setCode()
+ * @see execute()
+ */
+ public function run(InputInterface $input, OutputInterface $output): int
+ {
+ }
+
+ /**
+ * Adds suggestions to $suggestions for the current completion input (e.g. option or argument).
+ */
+ public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
+ {
+ }
+
+ /**
+ * Sets the code to execute when running this command.
+ *
+ * If this method is used, it overrides the code defined
+ * in the execute() method.
+ *
+ * @param callable $code A callable(InputInterface $input, OutputInterface $output)
+ *
+ * @return $this
+ *
+ * @throws InvalidArgumentException
+ *
+ * @see execute()
+ */
+ public function setCode(callable $code): static
+ {
+ }
+
+ /**
+ * Merges the application definition with the command definition.
+ *
+ * This method is not part of public API and should not be used directly.
+ *
+ * @param bool $mergeArgs Whether to merge or not the Application definition arguments to Command definition arguments
+ *
+ * @internal
+ */
+ public function mergeApplicationDefinition(bool $mergeArgs = true): void
+ {
+ }
+
+ /**
+ * Sets an array of argument and option instances.
+ *
+ * @return $this
+ */
+ public function setDefinition(array|InputDefinition $definition): static
+ {
+ }
+
+ /**
+ * Gets the InputDefinition attached to this Command.
+ */
+ public function getDefinition(): InputDefinition
+ {
+ }
+
+ /**
+ * Gets the InputDefinition to be used to create representations of this Command.
+ *
+ * Can be overridden to provide the original command representation when it would otherwise
+ * be changed by merging with the application InputDefinition.
+ *
+ * This method is not part of public API and should not be used directly.
+ */
+ public function getNativeDefinition(): InputDefinition
+ {
+ }
+
+ /**
+ * Adds an argument.
+ *
+ * @param $mode The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL
+ * @param $default The default value (for InputArgument::OPTIONAL mode only)
+ * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion
+ *
+ * @return $this
+ *
+ * @throws InvalidArgumentException When argument mode is not valid
+ */
+ public function addArgument(string $name, ?int $mode = null, string $description = '', mixed $default = null): static
+ {
+ }
+
+ /**
+ * Adds an option.
+ *
+ * @param $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
+ * @param $mode The option mode: One of the InputOption::VALUE_* constants
+ * @param $default The default value (must be null for InputOption::VALUE_NONE)
+ * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion
+ *
+ * @return $this
+ *
+ * @throws InvalidArgumentException If option mode is invalid or incompatible
+ */
+ public function addOption(string $name, string|array|null $shortcut = null, ?int $mode = null, string $description = '', mixed $default = null): static
+ {
+ }
+
+ /**
+ * Sets the name of the command.
+ *
+ * This method can set both the namespace and the name if
+ * you separate them by a colon (:)
+ *
+ * $command->setName('foo:bar');
+ *
+ * @return $this
+ *
+ * @throws InvalidArgumentException When the name is invalid
+ */
+ public function setName(string $name): static
+ {
+ }
+
+ /**
+ * Sets the process title of the command.
+ *
+ * This feature should be used only when creating a long process command,
+ * like a daemon.
+ *
+ * @return $this
+ */
+ public function setProcessTitle(string $title): static
+ {
+ }
+
+ /**
+ * Returns the command name.
+ */
+ public function getName(): ?string
+ {
+ }
+
+ /**
+ * @param bool $hidden Whether or not the command should be hidden from the list of commands
+ *
+ * @return $this
+ */
+ public function setHidden(bool $hidden = true): static
+ {
+ }
+
+ /**
+ * @return bool whether the command should be publicly shown or not
+ */
+ public function isHidden(): bool
+ {
+ }
+
+ /**
+ * Sets the description for the command.
+ *
+ * @return $this
+ */
+ public function setDescription(string $description): static
+ {
+ }
+
+ /**
+ * Returns the description for the command.
+ */
+ public function getDescription(): string
+ {
+ }
+
+ /**
+ * Sets the help for the command.
+ *
+ * @return $this
+ */
+ public function setHelp(string $help): static
+ {
+ }
+
+ /**
+ * Returns the help for the command.
+ */
+ public function getHelp(): string
+ {
+ }
+
+ /**
+ * Returns the processed help for the command replacing the %command.name% and
+ * %command.full_name% patterns with the real values dynamically.
+ */
+ public function getProcessedHelp(): string
+ {
+ }
+
+ /**
+ * Sets the aliases for the command.
+ *
+ * @param string[] $aliases An array of aliases for the command
+ *
+ * @return $this
+ *
+ * @throws InvalidArgumentException When an alias is invalid
+ */
+ public function setAliases(iterable $aliases): static
+ {
+ }
+
+ /**
+ * Returns the aliases for the command.
+ */
+ public function getAliases(): array
+ {
+ }
+
+ /**
+ * Returns the synopsis for the command.
+ *
+ * @param bool $short Whether to show the short version of the synopsis (with options folded) or not
+ */
+ public function getSynopsis(bool $short = false): string
+ {
+ }
+
+ /**
+ * Add a command usage example, it'll be prefixed with the command name.
+ *
+ * @return $this
+ */
+ public function addUsage(string $usage): static
+ {
+ }
+
+ /**
+ * Returns alternative usages of the command.
+ */
+ public function getUsages(): array
+ {
+ }
+
+ /**
+ * Gets a helper instance by name.
+ *
+ * @return HelperInterface
+ *
+ * @throws LogicException if no HelperSet is defined
+ * @throws InvalidArgumentException if the helper is not defined
+ */
+ public function getHelper(string $name): mixed
+ {
+ }
+}
diff --git a/tests/stubs/symfony_component_console_helper_table.php b/tests/stubs/symfony_component_console_helper_table.php
new file mode 100644
index 00000000..373b3fff
--- /dev/null
+++ b/tests/stubs/symfony_component_console_helper_table.php
@@ -0,0 +1,218 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+use Symfony\Component\Console\Exception\RuntimeException;
+use Symfony\Component\Console\Formatter\OutputFormatter;
+use Symfony\Component\Console\Formatter\WrappableOutputFormatterInterface;
+use Symfony\Component\Console\Output\ConsoleSectionOutput;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Provides helpers to display a table.
+ *
+ * @author Fabien Potencier
+ * @author Саша Стаменковић
+ * @author Abdellatif Ait boudad
+ * @author Max Grigorian
+ * @author Dany Maillard
+ */
+class Table
+{
+ private const SEPARATOR_TOP = 0;
+ private const SEPARATOR_TOP_BOTTOM = 1;
+ private const SEPARATOR_MID = 2;
+ private const SEPARATOR_BOTTOM = 3;
+ private const BORDER_OUTSIDE = 0;
+ private const BORDER_INSIDE = 1;
+ private const DISPLAY_ORIENTATION_DEFAULT = 'default';
+ private const DISPLAY_ORIENTATION_HORIZONTAL = 'horizontal';
+ private const DISPLAY_ORIENTATION_VERTICAL = 'vertical';
+
+ public function __construct(OutputInterface $output)
+ {
+ }
+
+ /**
+ * Sets a style definition.
+ *
+ * @return void
+ */
+ public static function setStyleDefinition(string $name, TableStyle $style)
+ {
+ }
+
+ /**
+ * Gets a style definition by name.
+ */
+ public static function getStyleDefinition(string $name): TableStyle
+ {
+ }
+
+ /**
+ * Sets table style.
+ *
+ * @return $this
+ */
+ public function setStyle(TableStyle|string $name): static
+ {
+ }
+
+ /**
+ * Gets the current table style.
+ */
+ public function getStyle(): TableStyle
+ {
+ }
+
+ /**
+ * Sets table column style.
+ *
+ * @param TableStyle|string $name The style name or a TableStyle instance
+ *
+ * @return $this
+ */
+ public function setColumnStyle(int $columnIndex, TableStyle|string $name): static
+ {
+ }
+
+ /**
+ * Gets the current style for a column.
+ *
+ * If style was not set, it returns the global table style.
+ */
+ public function getColumnStyle(int $columnIndex): TableStyle
+ {
+ }
+
+ /**
+ * Sets the minimum width of a column.
+ *
+ * @return $this
+ */
+ public function setColumnWidth(int $columnIndex, int $width): static
+ {
+ }
+
+ /**
+ * Sets the minimum width of all columns.
+ *
+ * @return $this
+ */
+ public function setColumnWidths(array $widths): static
+ {
+ }
+
+ /**
+ * Sets the maximum width of a column.
+ *
+ * Any cell within this column which contents exceeds the specified width will be wrapped into multiple lines, while
+ * formatted strings are preserved.
+ *
+ * @return $this
+ */
+ public function setColumnMaxWidth(int $columnIndex, int $width): static
+ {
+ }
+
+ /**
+ * @return $this
+ */
+ public function setHeaders(array $headers): static
+ {
+ }
+
+ /**
+ * @return $this
+ */
+ public function setRows(array $rows)
+ {
+ }
+
+ /**
+ * @return $this
+ */
+ public function addRows(array $rows): static
+ {
+ }
+
+ /**
+ * @return $this
+ */
+ public function addRow(TableSeparator|array $row): static
+ {
+ }
+
+ /**
+ * Adds a row to the table, and re-renders the table.
+ *
+ * @return $this
+ */
+ public function appendRow(TableSeparator|array $row): static
+ {
+ }
+
+ /**
+ * @return $this
+ */
+ public function setRow(int|string $column, array $row): static
+ {
+ }
+
+ /**
+ * @return $this
+ */
+ public function setHeaderTitle(?string $title): static
+ {
+ }
+
+ /**
+ * @return $this
+ */
+ public function setFooterTitle(?string $title): static
+ {
+ }
+
+ /**
+ * @return $this
+ */
+ public function setHorizontal(bool $horizontal = true): static
+ {
+ }
+
+ /**
+ * @return $this
+ */
+ public function setVertical(bool $vertical = true): static
+ {
+ }
+
+ /**
+ * Renders table to output.
+ *
+ * Example:
+ *
+ * +---------------+-----------------------+------------------+
+ * | ISBN | Title | Author |
+ * +---------------+-----------------------+------------------+
+ * | 99921-58-10-7 | Divine Comedy | Dante Alighieri |
+ * | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
+ * | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
+ * +---------------+-----------------------+------------------+
+ *
+ * @return void
+ */
+ public function render()
+ {
+ }
+}
diff --git a/tests/stubs/symfony_component_console_input_inputargument.php b/tests/stubs/symfony_component_console_input_inputargument.php
new file mode 100644
index 00000000..8a106813
--- /dev/null
+++ b/tests/stubs/symfony_component_console_input_inputargument.php
@@ -0,0 +1,107 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Completion\CompletionInput;
+use Symfony\Component\Console\Completion\CompletionSuggestions;
+use Symfony\Component\Console\Completion\Suggestion;
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+use Symfony\Component\Console\Exception\LogicException;
+
+/**
+ * Represents a command line argument.
+ *
+ * @author Fabien Potencier
+ */
+class InputArgument
+{
+ public const REQUIRED = 1;
+ public const OPTIONAL = 2;
+ public const IS_ARRAY = 4;
+
+ /**
+ * @param string $name The argument name
+ * @param int|null $mode The argument mode: a bit mask of self::REQUIRED, self::OPTIONAL and self::IS_ARRAY
+ * @param string $description A description text
+ * @param string|bool|int|float|array|null $default The default value (for self::OPTIONAL mode only)
+ * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion
+ *
+ * @throws InvalidArgumentException When argument mode is not valid
+ */
+ public function __construct(string $name, ?int $mode = null, string $description = '', string|bool|int|float|array|null $default = null, \Closure|array $suggestedValues = [])
+ {
+ }
+
+ /**
+ * Returns the argument name.
+ */
+ public function getName(): string
+ {
+ }
+
+ /**
+ * Returns true if the argument is required.
+ *
+ * @return bool true if parameter mode is self::REQUIRED, false otherwise
+ */
+ public function isRequired(): bool
+ {
+ }
+
+ /**
+ * Returns true if the argument can take multiple values.
+ *
+ * @return bool true if mode is self::IS_ARRAY, false otherwise
+ */
+ public function isArray(): bool
+ {
+ }
+
+ /**
+ * Sets the default value.
+ *
+ * @return void
+ *
+ * @throws LogicException When incorrect default value is given
+ */
+ public function setDefault(string|bool|int|float|array|null $default = null)
+ {
+ }
+
+ /**
+ * Returns the default value.
+ */
+ public function getDefault(): string|bool|int|float|array|null
+ {
+ }
+
+ public function hasCompletion(): bool
+ {
+ }
+
+ /**
+ * Adds suggestions to $suggestions for the current completion input.
+ *
+ * @see Command::complete()
+ */
+ public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
+ {
+ }
+
+ /**
+ * Returns the description text.
+ */
+ public function getDescription(): string
+ {
+ }
+}
diff --git a/tests/stubs/symfony_component_console_input_inputinterface.php b/tests/stubs/symfony_component_console_input_inputinterface.php
new file mode 100644
index 00000000..352937c6
--- /dev/null
+++ b/tests/stubs/symfony_component_console_input_inputinterface.php
@@ -0,0 +1,180 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+use Symfony\Component\Console\Exception\RuntimeException;
+
+/**
+ * InputInterface is the interface implemented by all input classes.
+ *
+ * @author Fabien Potencier
+ *
+ * @method string __toString() Returns a stringified representation of the args passed to the command.
+ * InputArguments MUST be escaped as well as the InputOption values passed to the command.
+ */
+interface InputInterface
+{
+ /**
+ * Returns the first argument from the raw parameters (not parsed).
+ */
+ public function getFirstArgument(): ?string
+ {
+ }
+
+ /**
+ * Returns true if the raw parameters (not parsed) contain a value.
+ *
+ * This method is to be used to introspect the input parameters
+ * before they have been validated. It must be used carefully.
+ * Does not necessarily return the correct result for short options
+ * when multiple flags are combined in the same option.
+ *
+ * @param string|array $values The values to look for in the raw parameters (can be an array)
+ * @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal
+ */
+ public function hasParameterOption(string|array $values, bool $onlyParams = false): bool
+ {
+ }
+
+ /**
+ * Returns the value of a raw option (not parsed).
+ *
+ * This method is to be used to introspect the input parameters
+ * before they have been validated. It must be used carefully.
+ * Does not necessarily return the correct result for short options
+ * when multiple flags are combined in the same option.
+ *
+ * @param string|array $values The value(s) to look for in the raw parameters (can be an array)
+ * @param string|bool|int|float|array|null $default The default value to return if no result is found
+ * @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal
+ *
+ * @return mixed
+ */
+ public function getParameterOption(string|array $values, string|bool|int|float|array|null $default = false, bool $onlyParams = false)
+ {
+ }
+
+ /**
+ * Binds the current Input instance with the given arguments and options.
+ *
+ * @return void
+ *
+ * @throws RuntimeException
+ */
+ public function bind(InputDefinition $definition)
+ {
+ }
+
+ /**
+ * Validates the input.
+ *
+ * @return void
+ *
+ * @throws RuntimeException When not enough arguments are given
+ */
+ public function validate()
+ {
+ }
+
+ /**
+ * Returns all the given arguments merged with the default values.
+ *
+ * @return array
+ */
+ public function getArguments(): array
+ {
+ }
+
+ /**
+ * Returns the argument value for a given argument name.
+ *
+ * @return mixed
+ *
+ * @throws InvalidArgumentException When argument given doesn't exist
+ */
+ public function getArgument(string $name)
+ {
+ }
+
+ /**
+ * Sets an argument value by name.
+ *
+ * @return void
+ *
+ * @throws InvalidArgumentException When argument given doesn't exist
+ */
+ public function setArgument(string $name, mixed $value)
+ {
+ }
+
+ /**
+ * Returns true if an InputArgument object exists by name or position.
+ */
+ public function hasArgument(string $name): bool
+ {
+ }
+
+ /**
+ * Returns all the given options merged with the default values.
+ *
+ * @return array
+ */
+ public function getOptions(): array
+ {
+ }
+
+ /**
+ * Returns the option value for a given option name.
+ *
+ * @return mixed
+ *
+ * @throws InvalidArgumentException When option given doesn't exist
+ */
+ public function getOption(string $name)
+ {
+ }
+
+ /**
+ * Sets an option value by name.
+ *
+ * @return void
+ *
+ * @throws InvalidArgumentException When option given doesn't exist
+ */
+ public function setOption(string $name, mixed $value)
+ {
+ }
+
+ /**
+ * Returns true if an InputOption object exists by name.
+ */
+ public function hasOption(string $name): bool
+ {
+ }
+
+ /**
+ * Is this input means interactive?
+ */
+ public function isInteractive(): bool
+ {
+ }
+
+ /**
+ * Sets the input interactivity.
+ *
+ * @return void
+ */
+ public function setInteractive(bool $interactive)
+ {
+ }
+}
diff --git a/tests/stubs/symfony_component_console_input_inputoption.php b/tests/stubs/symfony_component_console_input_inputoption.php
new file mode 100644
index 00000000..ab5680e5
--- /dev/null
+++ b/tests/stubs/symfony_component_console_input_inputoption.php
@@ -0,0 +1,159 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Completion\CompletionInput;
+use Symfony\Component\Console\Completion\CompletionSuggestions;
+use Symfony\Component\Console\Completion\Suggestion;
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+use Symfony\Component\Console\Exception\LogicException;
+
+/**
+ * Represents a command line option.
+ *
+ * @author Fabien Potencier
+ */
+class InputOption
+{
+ /**
+ * Do not accept input for the option (e.g. --yell). This is the default behavior of options.
+ */
+ public const VALUE_NONE = 1;
+
+ /**
+ * A value must be passed when the option is used (e.g. --iterations=5 or -i5).
+ */
+ public const VALUE_REQUIRED = 2;
+
+ /**
+ * The option may or may not have a value (e.g. --yell or --yell=loud).
+ */
+ public const VALUE_OPTIONAL = 4;
+
+ /**
+ * The option accepts multiple values (e.g. --dir=/foo --dir=/bar).
+ */
+ public const VALUE_IS_ARRAY = 8;
+
+ /**
+ * The option may have either positive or negative value (e.g. --ansi or --no-ansi).
+ */
+ public const VALUE_NEGATABLE = 16;
+
+ /**
+ * @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
+ * @param int|null $mode The option mode: One of the VALUE_* constants
+ * @param string|bool|int|float|array|null $default The default value (must be null for self::VALUE_NONE)
+ * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion
+ *
+ * @throws InvalidArgumentException If option mode is invalid or incompatible
+ */
+ public function __construct(string $name, string|array|null $shortcut = null, ?int $mode = null, string $description = '', string|bool|int|float|array|null $default = null, array|\Closure $suggestedValues = [])
+ {
+ }
+
+ /**
+ * Returns the option shortcut.
+ */
+ public function getShortcut(): ?string
+ {
+ }
+
+ /**
+ * Returns the option name.
+ */
+ public function getName(): string
+ {
+ }
+
+ /**
+ * Returns true if the option accepts a value.
+ *
+ * @return bool true if value mode is not self::VALUE_NONE, false otherwise
+ */
+ public function acceptValue(): bool
+ {
+ }
+
+ /**
+ * Returns true if the option requires a value.
+ *
+ * @return bool true if value mode is self::VALUE_REQUIRED, false otherwise
+ */
+ public function isValueRequired(): bool
+ {
+ }
+
+ /**
+ * Returns true if the option takes an optional value.
+ *
+ * @return bool true if value mode is self::VALUE_OPTIONAL, false otherwise
+ */
+ public function isValueOptional(): bool
+ {
+ }
+
+ /**
+ * Returns true if the option can take multiple values.
+ *
+ * @return bool true if mode is self::VALUE_IS_ARRAY, false otherwise
+ */
+ public function isArray(): bool
+ {
+ }
+
+ public function isNegatable(): bool
+ {
+ }
+
+ /**
+ * @return void
+ */
+ public function setDefault(string|bool|int|float|array|null $default = null)
+ {
+ }
+
+ /**
+ * Returns the default value.
+ */
+ public function getDefault(): string|bool|int|float|array|null
+ {
+ }
+
+ /**
+ * Returns the description text.
+ */
+ public function getDescription(): string
+ {
+ }
+
+ public function hasCompletion(): bool
+ {
+ }
+
+ /**
+ * Adds suggestions to $suggestions for the current completion input.
+ *
+ * @see Command::complete()
+ */
+ public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
+ {
+ }
+
+ /**
+ * Checks whether the given option equals this one.
+ */
+ public function equals(self $option): bool
+ {
+ }
+}
diff --git a/tests/stubs/symfony_component_console_output_outputinterface.php b/tests/stubs/symfony_component_console_output_outputinterface.php
new file mode 100644
index 00000000..f0b0b2f1
--- /dev/null
+++ b/tests/stubs/symfony_component_console_output_outputinterface.php
@@ -0,0 +1,135 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+use Symfony\Component\Console\Formatter\OutputFormatterInterface;
+
+/**
+ * OutputInterface is the interface implemented by all Output classes.
+ *
+ * @author Fabien Potencier
+ */
+interface OutputInterface
+{
+ public const VERBOSITY_QUIET = 16;
+ public const VERBOSITY_NORMAL = 32;
+ public const VERBOSITY_VERBOSE = 64;
+ public const VERBOSITY_VERY_VERBOSE = 128;
+ public const VERBOSITY_DEBUG = 256;
+
+ public const OUTPUT_NORMAL = 1;
+ public const OUTPUT_RAW = 2;
+ public const OUTPUT_PLAIN = 4;
+
+ /**
+ * Writes a message to the output.
+ *
+ * @param bool $newline Whether to add a newline
+ * @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants),
+ * 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL
+ *
+ * @return void
+ */
+ public function write(string|iterable $messages, bool $newline = false, int $options = 0)
+ {
+ }
+
+ /**
+ * Writes a message to the output and adds a newline at the end.
+ *
+ * @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants),
+ * 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL
+ *
+ * @return void
+ */
+ public function writeln(string|iterable $messages, int $options = 0)
+ {
+ }
+
+ /**
+ * Sets the verbosity of the output.
+ *
+ * @param self::VERBOSITY_* $level
+ *
+ * @return void
+ */
+ public function setVerbosity(int $level)
+ {
+ }
+
+ /**
+ * Gets the current verbosity of the output.
+ *
+ * @return self::VERBOSITY_*
+ */
+ public function getVerbosity(): int
+ {
+ }
+
+ /**
+ * Returns whether verbosity is quiet (-q).
+ */
+ public function isQuiet(): bool
+ {
+ }
+
+ /**
+ * Returns whether verbosity is verbose (-v).
+ */
+ public function isVerbose(): bool
+ {
+ }
+
+ /**
+ * Returns whether verbosity is very verbose (-vv).
+ */
+ public function isVeryVerbose(): bool
+ {
+ }
+
+ /**
+ * Returns whether verbosity is debug (-vvv).
+ */
+ public function isDebug(): bool
+ {
+ }
+
+ /**
+ * Sets the decorated flag.
+ *
+ * @return void
+ */
+ public function setDecorated(bool $decorated)
+ {
+ }
+
+ /**
+ * Gets the decorated flag.
+ */
+ public function isDecorated(): bool
+ {
+ }
+
+ /**
+ * @return void
+ */
+ public function setFormatter(OutputFormatterInterface $formatter)
+ {
+ }
+
+ /**
+ * Returns current output formatter instance.
+ */
+ public function getFormatter(): OutputFormatterInterface
+ {
+ }
+}
diff --git a/tests/stubs/symfony_component_console_question_confirmationquestion.php b/tests/stubs/symfony_component_console_question_confirmationquestion.php
new file mode 100644
index 00000000..0db6fe2f
--- /dev/null
+++ b/tests/stubs/symfony_component_console_question_confirmationquestion.php
@@ -0,0 +1,29 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Question;
+
+/**
+ * Represents a yes/no question.
+ *
+ * @author Fabien Potencier
+ */
+class ConfirmationQuestion extends Question
+{
+ /**
+ * @param string $question The question to ask to the user
+ * @param bool $default The default answer to return, true or false
+ * @param string $trueAnswerRegex A regex to match the "yes" answer
+ */
+ public function __construct(string $question, bool $default = true, string $trueAnswerRegex = '/^y/i')
+ {
+ }
+}
diff --git a/tests/stubs/symfony_component_console_question_question.php b/tests/stubs/symfony_component_console_question_question.php
new file mode 100644
index 00000000..c04b412b
--- /dev/null
+++ b/tests/stubs/symfony_component_console_question_question.php
@@ -0,0 +1,207 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Question;
+
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+use Symfony\Component\Console\Exception\LogicException;
+
+/**
+ * Represents a Question.
+ *
+ * @author Fabien Potencier
+ */
+class Question
+{
+ /**
+ * @param string $question The question to ask to the user
+ * @param string|bool|int|float|null $default The default answer to return if the user enters nothing
+ */
+ public function __construct(string $question, string|bool|int|float|null $default = null)
+ {
+ }
+
+ /**
+ * Returns the question.
+ */
+ public function getQuestion(): string
+ {
+ }
+
+ /**
+ * Returns the default answer.
+ */
+ public function getDefault(): string|bool|int|float|null
+ {
+ }
+
+ /**
+ * Returns whether the user response accepts newline characters.
+ */
+ public function isMultiline(): bool
+ {
+ }
+
+ /**
+ * Sets whether the user response should accept newline characters.
+ *
+ * @return $this
+ */
+ public function setMultiline(bool $multiline): static
+ {
+ }
+
+ /**
+ * Returns whether the user response must be hidden.
+ */
+ public function isHidden(): bool
+ {
+ }
+
+ /**
+ * Sets whether the user response must be hidden or not.
+ *
+ * @return $this
+ *
+ * @throws LogicException In case the autocompleter is also used
+ */
+ public function setHidden(bool $hidden): static
+ {
+ }
+
+ /**
+ * In case the response cannot be hidden, whether to fallback on non-hidden question or not.
+ */
+ public function isHiddenFallback(): bool
+ {
+ }
+
+ /**
+ * Sets whether to fallback on non-hidden question if the response cannot be hidden.
+ *
+ * @return $this
+ */
+ public function setHiddenFallback(bool $fallback): static
+ {
+ }
+
+ /**
+ * Gets values for the autocompleter.
+ */
+ public function getAutocompleterValues(): ?iterable
+ {
+ }
+
+ /**
+ * Sets values for the autocompleter.
+ *
+ * @return $this
+ *
+ * @throws LogicException
+ */
+ public function setAutocompleterValues(?iterable $values): static
+ {
+ }
+
+ /**
+ * Gets the callback function used for the autocompleter.
+ */
+ public function getAutocompleterCallback(): ?callable
+ {
+ }
+
+ /**
+ * Sets the callback function used for the autocompleter.
+ *
+ * The callback is passed the user input as argument and should return an iterable of corresponding suggestions.
+ *
+ * @return $this
+ */
+ public function setAutocompleterCallback(?callable $callback = null): static
+ {
+ }
+
+ /**
+ * Sets a validator for the question.
+ *
+ * @return $this
+ */
+ public function setValidator(?callable $validator = null): static
+ {
+ }
+
+ /**
+ * Gets the validator for the question.
+ */
+ public function getValidator(): ?callable
+ {
+ }
+
+ /**
+ * Sets the maximum number of attempts.
+ *
+ * Null means an unlimited number of attempts.
+ *
+ * @return $this
+ *
+ * @throws InvalidArgumentException in case the number of attempts is invalid
+ */
+ public function setMaxAttempts(?int $attempts): static
+ {
+ }
+
+ /**
+ * Gets the maximum number of attempts.
+ *
+ * Null means an unlimited number of attempts.
+ */
+ public function getMaxAttempts(): ?int
+ {
+ }
+
+ /**
+ * Sets a normalizer for the response.
+ *
+ * The normalizer can be a callable (a string), a closure or a class implementing __invoke.
+ *
+ * @return $this
+ */
+ public function setNormalizer(callable $normalizer): static
+ {
+ }
+
+ /**
+ * Gets the normalizer for the response.
+ *
+ * The normalizer can ba a callable (a string), a closure or a class implementing __invoke.
+ */
+ public function getNormalizer(): ?callable
+ {
+ }
+
+ /**
+ * @return bool
+ */
+ protected function isAssoc(array $array)
+ {
+ }
+
+ public function isTrimmable(): bool
+ {
+ }
+
+ /**
+ * @return $this
+ */
+ public function setTrimmable(bool $trimmable): static
+ {
+ }
+}