From 6a6f47bb18ee959be9275967ca8609dfeec00521 Mon Sep 17 00:00:00 2001 From: AdrienClairembault Date: Thu, 14 Aug 2025 14:31:47 +0200 Subject: [PATCH] Review the empty plugin - Fix spelling mistakes and punctuation inconsistencies - Fix incorrect license - Add global modified to sed commands to fix missed replacements - Rename master to main - Fix headers - Update glpi-project/tools to ^0.7 - Add empty src folder - Add makefile - Add phpunit - Add PHPStan - Add PHP-CS-Fixer - Add CI workflow --- .github/workflows/continuous-integration.yml | 36 +++++++++++ .../workflows/continuous-integration.yml.tpl | 35 +++++++++++ .github/workflows/create-plugin.sh | 38 ++++++++++++ .gitignore | 2 +- .php-cs-fixer.php | 52 ++++++++++++++++ Makefile | 1 + composer.json | 2 +- hook.php.tpl | 16 +++-- phpstan.neon | 16 +++++ phpunit.xml | 7 +++ plugin.sh | 28 +++++---- plugin.xml | 14 ++--- setup.php.tpl | 62 +++++++++++-------- src/.gitkeep | 0 tests/bootstrap.php | 47 ++++++++++++++ 15 files changed, 301 insertions(+), 55 deletions(-) create mode 100644 .github/workflows/continuous-integration.yml create mode 100644 .github/workflows/continuous-integration.yml.tpl create mode 100644 .github/workflows/create-plugin.sh create mode 100644 .php-cs-fixer.php create mode 100644 Makefile create mode 100644 phpstan.neon create mode 100644 phpunit.xml create mode 100644 src/.gitkeep create mode 100644 tests/bootstrap.php diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml new file mode 100644 index 0000000..240ec5c --- /dev/null +++ b/.github/workflows/continuous-integration.yml @@ -0,0 +1,36 @@ +name: "Continuous integration" + +on: + push: + branches: + - "main" + tags: + - "*" + pull_request: + schedule: + - cron: "0 0 * * *" + workflow_dispatch: + +concurrency: + group: "${{ github.workflow }}-${{ github.ref }}" + cancel-in-progress: true + +jobs: + generate-ci-matrix: + name: "Generate CI matrix" + uses: "glpi-project/plugin-ci-workflows/.github/workflows/generate-ci-matrix.yml@v1" + with: + glpi-version: "10.0.x" + ci: + name: "GLPI ${{ matrix.glpi-version }} - php:${{ matrix.php-version }} - ${{ matrix.db-image }}" + needs: "generate-ci-matrix" + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.generate-ci-matrix.outputs.matrix) }} + uses: "glpi-project/plugin-ci-workflows/.github/workflows/continuous-integration.yml@v1" + with: + plugin-key: "empty" + glpi-version: "${{ matrix.glpi-version }}" + php-version: "${{ matrix.php-version }}" + db-image: "${{ matrix.db-image }}" + init-script: "./.github/workflows/create-plugin.sh" diff --git a/.github/workflows/continuous-integration.yml.tpl b/.github/workflows/continuous-integration.yml.tpl new file mode 100644 index 0000000..f6a0b20 --- /dev/null +++ b/.github/workflows/continuous-integration.yml.tpl @@ -0,0 +1,35 @@ +name: "Continuous integration" + +on: + push: + branches: + - "main" + tags: + - "*" + pull_request: + schedule: + - cron: "0 0 * * *" + workflow_dispatch: + +concurrency: + group: "${{ github.workflow }}-${{ github.ref }}" + cancel-in-progress: true + +jobs: + generate-ci-matrix: + name: "Generate CI matrix" + uses: "glpi-project/plugin-ci-workflows/.github/workflows/generate-ci-matrix.yml@v1" + with: + glpi-version: "10.0.x" + ci: + name: "GLPI ${{ matrix.glpi-version }} - php:${{ matrix.php-version }} - ${{ matrix.db-image }}" + needs: "generate-ci-matrix" + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.generate-ci-matrix.outputs.matrix) }} + uses: "glpi-project/plugin-ci-workflows/.github/workflows/continuous-integration.yml@v1" + with: + plugin-key: "{LNAME}" + glpi-version: "${{ matrix.glpi-version }}" + php-version: "${{ matrix.php-version }}" + db-image: "${{ matrix.db-image }}" diff --git a/.github/workflows/create-plugin.sh b/.github/workflows/create-plugin.sh new file mode 100644 index 0000000..a4c00b9 --- /dev/null +++ b/.github/workflows/create-plugin.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# +# ------------------------------------------------------------------------- +# {NAME} plugin for GLPI +# Copyright (C) {YEAR} by the {NAME} Development Team. +# ------------------------------------------------------------------------- +# +# MIT License +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# -------------------------------------------------------------------------- +# + +set -e -u -o pipefail + +# `rsync` is required by the `plugin.sh` script +sudo apt update +sudo apt install --assume-yes --no-install-recommends --quiet rsync + +# move self to `template` then create an `empty` plugin` +(cd .. && mv empty template && cd template && ./plugin.sh empty "1.0.0") diff --git a/.gitignore b/.gitignore index f9813e5..331eec8 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,4 @@ vendor/ .gh_token composer.lock *.min.* - +var diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php new file mode 100644 index 0000000..0262287 --- /dev/null +++ b/.php-cs-fixer.php @@ -0,0 +1,52 @@ +in(__DIR__) + ->ignoreVCSIgnored(true) + ->name('*.php'); + +$config = new Config(); + +$rules = [ + '@PER-CS' => true, // Latest PER rules. +]; + +return $config + ->setRules($rules) + ->setFinder($finder) + ->setCacheFile(__DIR__ . '/var/php-cs-fixer/.php-cs-fixer.cache') +; diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ef1bed5 --- /dev/null +++ b/Makefile @@ -0,0 +1 @@ +include ../../PluginsMakefile.mk diff --git a/composer.json b/composer.json index 80f27e8..64b664b 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "php": ">=7.4" }, "require-dev": { - "glpi-project/tools": "^0.4" + "glpi-project/tools": "^0.7" }, "config": { "optimize-autoloader": true, diff --git a/hook.php.tpl b/hook.php.tpl index 59306d1..eb19b2d 100644 --- a/hook.php.tpl +++ b/hook.php.tpl @@ -3,7 +3,6 @@ /** * ------------------------------------------------------------------------- * {NAME} plugin for GLPI - * Copyright (C) {YEAR} by the {NAME} Development Team. * ------------------------------------------------------------------------- * * MIT License @@ -25,26 +24,25 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * -------------------------------------------------------------------------- + * ------------------------------------------------------------------------- + * @copyright Copyright (C) {YEAR} by the {NAME} plugin team. + * @license MIT https://opensource.org/licenses/mit-license.php + * @link https://github.com/pluginsGLPI/{LNAME} + * ------------------------------------------------------------------------- */ /** * Plugin install process - * - * @return boolean */ -function plugin_{LNAME}_install() +function plugin_{LNAME}_install(): bool { return true; } /** * Plugin uninstall process - * - * @return boolean */ -function plugin_{LNAME}_uninstall() +function plugin_{LNAME}_uninstall(): bool { return true; } diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..d56d9b3 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,16 @@ +includes: + - ../../vendor/phpstan/phpstan-deprecation-rules/rules.neon + +parameters: + level: max + paths: + - src + - hook.php + - setup.php + scanDirectories: + - ../../src + bootstrapFiles: + - ../../inc/based_config.php + stubFiles: + - ../../stubs/glpi_constants.php + treatPhpDocTypesAsCertain: false diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..74c8686 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,7 @@ + + + + tests + + + diff --git a/plugin.sh b/plugin.sh index 0da7102..c2f6025 100755 --- a/plugin.sh +++ b/plugin.sh @@ -28,6 +28,8 @@ # -------------------------------------------------------------------------- # +set -e -u -o pipefail + if [[ $# -ne 2 && $# -ne 3 ]]; then echo $0: usage: plugin.sh name version [destination/path] exit 1 @@ -61,6 +63,8 @@ mkdir "$DEST" rsync \ --exclude '.git' \ + --exclude '.github/workflows/continuous-integration.yml' \ + --exclude '.github/workflows/create-plugin.sh' \ --exclude 'plugin.sh' \ --exclude 'dist' \ --exclude 'README.md' \ @@ -68,22 +72,24 @@ rsync \ pushd "$DEST" > /dev/null -#rename .tpl... -for f in `ls *.tpl` -do - mv $f ${f%.*} -done +# Remove .tpl suffix (current folder and subdirectories) +# Note: the .tpl suffix is used to prevent some files from being detected by +# GLPI (like the setup.php) or github (the ci configuration). +find . -type f -name "*.tpl" -exec bash -c 'mv "$0" "${0%.*}"' {} \; # move xml file mv plugin.xml $LNAME.xml #do replacements sed \ - -e "s/{NAME}/$NAME/" \ - -e "s/{LNAME}/$LNAME/" \ - -e "s/{UNAME}/$UNAME/" \ - -e "s/{VERSION}/$VERSION/" \ - -e "s/{YEAR}/$YEAR/" \ - -i setup.php hook.php $LNAME.xml tools/HEADER README.md + -e "s/{NAME}/$NAME/g" \ + -e "s/{LNAME}/$LNAME/g" \ + -e "s/{UNAME}/$UNAME/g" \ + -e "s/{VERSION}/$VERSION/g" \ + -e "s/{YEAR}/$YEAR/g" \ + -i setup.php hook.php $LNAME.xml tools/HEADER README.md Makefile .github/workflows/continuous-integration.yml tests/bootstrap.php composer.json + +# Unignore composer lock +sed -i '/^[[:space:]]*composer\.lock[[:space:]]*$/d' .gitignore popd > /dev/null diff --git a/plugin.xml b/plugin.xml index a942825..41eb963 100644 --- a/plugin.xml +++ b/plugin.xml @@ -3,23 +3,23 @@ {LNAME} stable - https://raw.githubusercontent.com/pluginsGLPI/{LNAME}/master/{LNAME}.png + https://raw.githubusercontent.com/pluginsGLPI/{LNAME}/main/{LNAME}.png - {NAME} GLPI plugin. + {NAME} GLPI plugin Plugin GLPI {NAME} A long description for {NAME} GLPI plugin. - Un description longue pour le plugin GLPI {NAME} + Une description longue pour le plugin GLPI {NAME}. https://github.com/pluginsGLPI/{LNAME} https://github.com/pluginsGLPI/{LNAME}/releases https://github.com/pluginsGLPI/{LNAME}/issues - https://github.com/pluginsGLPI/{LNAME}/blob/master/README.md + https://github.com/pluginsGLPI/{LNAME}/blob/main/README.md Teclib' @@ -39,7 +39,7 @@ en_GB fr_FR - GPL V3+ + MIT diff --git a/setup.php.tpl b/setup.php.tpl index bba7014..82747f5 100644 --- a/setup.php.tpl +++ b/setup.php.tpl @@ -3,7 +3,6 @@ /** * ------------------------------------------------------------------------- * {NAME} plugin for GLPI - * Copyright (C) {YEAR} by the {NAME} Development Team. * ------------------------------------------------------------------------- * * MIT License @@ -25,38 +24,52 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * -------------------------------------------------------------------------- + * ------------------------------------------------------------------------- + * @copyright Copyright (C) {YEAR} by the {NAME} plugin team. + * @license MIT https://opensource.org/licenses/mit-license.php + * @link https://github.com/pluginsGLPI/{LNAME} + * ------------------------------------------------------------------------- */ define('PLUGIN_{UNAME}_VERSION', '{VERSION}'); // Minimal GLPI version, inclusive define("PLUGIN_{UNAME}_MIN_GLPI_VERSION", "10.0.0"); + // Maximum GLPI version, exclusive define("PLUGIN_{UNAME}_MAX_GLPI_VERSION", "10.0.99"); /** * Init hooks of the plugin. * REQUIRED - * - * @return void */ -function plugin_init_{LNAME}() +function plugin_init_{LNAME}(): void { + /** @var array> $PLUGIN_HOOKS */ global $PLUGIN_HOOKS; $PLUGIN_HOOKS['csrf_compliant']['{LNAME}'] = true; } - /** * Get the name and the version of the plugin * REQUIRED * - * @return array + * @return array{ + * name: string, + * version: string, + * author: string, + * license: string, + * homepage: string, + * requirements: array{ + * glpi: array{ + * min: string, + * max: string, + * } + * } + * } */ -function plugin_version_{LNAME}() +function plugin_version_{LNAME}(): array { return [ 'name' => '{NAME}', @@ -68,37 +81,34 @@ function plugin_version_{LNAME}() 'glpi' => [ 'min' => PLUGIN_{UNAME}_MIN_GLPI_VERSION, 'max' => PLUGIN_{UNAME}_MAX_GLPI_VERSION, - ] - ] + ], + ], ]; } /** * Check pre-requisites before install - * OPTIONNAL, but recommanded - * - * @return boolean + * OPTIONAL */ -function plugin_{LNAME}_check_prerequisites() +function plugin_{LNAME}_check_prerequisites(): bool { return true; } /** * Check configuration process + * OPTIONAL * - * @param boolean $verbose Whether to display message on failure. Defaults to false - * - * @return boolean + * @param bool $verbose Whether to display message on failure. Defaults to false. */ -function plugin_{LNAME}_check_config($verbose = false) +function plugin_{LNAME}_check_config(bool $verbose = false): bool { - if (true) { // Your configuration check - return true; - } + // Your configuration check + return true; - if ($verbose) { - echo __('Installed / not configured', '{LNAME}'); - } - return false; + // Example: + // if ($verbose) { + // echo __('Installed / not configured', '{LNAME}'); + // } + // return false; } diff --git a/src/.gitkeep b/src/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000..f1a4b7e --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,47 @@ +