diff --git a/.gitattributes b/.gitattributes index 2630454..5b41632 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,9 +1,8 @@ +/.github export-ignore /tests export-ignore .gitattributes export-ignore .gitignore export-ignore .php_cs export-ignore -.scrutinizer.yml export-ignore -.travis.run-tests.sh export-ignore -.travis.yml export-ignore +Makefile export-ignore phpstan.neon export-ignore phpunit.xml export-ignore diff --git a/.github/workflows/integrate.yaml b/.github/workflows/integrate.yaml new file mode 100644 index 0000000..97b2a7e --- /dev/null +++ b/.github/workflows/integrate.yaml @@ -0,0 +1,215 @@ +name: "Integrate" + +on: + pull_request: + push: + branches: + - "master" + +jobs: + composer-json-lint: + name: "Lint composer.json" + + runs-on: "ubuntu-latest" + + strategy: + matrix: + php-version: + - "7.4" + + steps: + - name: "Checkout" + uses: "actions/checkout@v2" + + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + coverage: "none" + php-version: "${{ matrix.php-version }}" + tools: composer-normalize, composer-require-checker, composer-unused + + - name: "Get composer cache directory" + id: composercache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: "Cache dependencies" + uses: actions/cache@v2 + with: + path: ${{ steps.composercache.outputs.dir }} + key: ${{ runner.os }}-php-${{ matrix.php-version }}-${{ matrix.dependencies }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-php-${{ matrix.php-version }}-${{ matrix.dependencies }}-composer- + + - name: "Install dependencies" + run: "composer update --no-interaction --no-progress" + + - name: "Validate composer.json" + run: "composer validate --strict" + + - name: "Normalize composer.json" + run: "composer-normalize --dry-run" + + tests: + name: "Tests" + + runs-on: "ubuntu-latest" + + strategy: + matrix: + php-version: + - "7.4" + - "8.0" + + steps: + - name: "Checkout" + uses: "actions/checkout@v2" + + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + coverage: "none" + php-version: "${{ matrix.php-version }}" + ini-values: zend.assertions=1 + + - name: "Get composer cache directory" + id: composercache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: "Cache dependencies" + uses: actions/cache@v2 + with: + path: ${{ steps.composercache.outputs.dir }} + key: ${{ runner.os }}-php-${{ matrix.php-version }}-${{ matrix.dependencies }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-php-${{ matrix.php-version }}-${{ matrix.dependencies }}-composer- + + - name: "Install dependencies" + if: ${{ matrix.php-version != '8.0' }} + run: "composer update --no-interaction --no-progress" + + - name: "Install dependencies PHP 8.0" + if: ${{ matrix.php-version == '8.0' }} + run: "composer update --no-interaction --no-progress --ignore-platform-reqs" + + - name: "Run tests" + timeout-minutes: 3 + run: "vendor/bin/phpunit --no-coverage --no-logging" + + code-coverage: + name: "Code Coverage" + + runs-on: "ubuntu-latest" + + strategy: + matrix: + php-version: + - "7.4" + + steps: + - name: "Checkout" + uses: "actions/checkout@v2" + + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + coverage: "pcov" + php-version: "${{ matrix.php-version }}" + ini-values: zend.assertions=1 + + - name: "Get composer cache directory" + id: composercache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: "Cache dependencies" + uses: actions/cache@v2 + with: + path: ${{ steps.composercache.outputs.dir }} + key: ${{ runner.os }}-php-${{ matrix.php-version }}-${{ matrix.dependencies }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-php-${{ matrix.php-version }}-${{ matrix.dependencies }}-composer- + + - name: "Install dependencies" + run: "composer update --no-interaction --no-progress" + + - name: "Run tests" + timeout-minutes: 3 + run: "vendor/bin/phpunit --coverage-clover=coverage.xml" + + - name: "Send code coverage report to Codecov.io" + uses: codecov/codecov-action@v1 + with: + token: ${{ secrets.CODECOV_TOKEN }} + file: ./coverage.xml + fail_ci_if_error: true + + coding-standards: + name: "Coding Standards" + + runs-on: "ubuntu-latest" + + strategy: + matrix: + php-version: + - "7.4" + + steps: + - name: "Checkout" + uses: "actions/checkout@v2" + + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + coverage: "none" + php-version: "${{ matrix.php-version }}" + + - name: "Get composer cache directory" + id: composercache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: "Cache dependencies" + uses: actions/cache@v2 + with: + path: ${{ steps.composercache.outputs.dir }} + key: ${{ runner.os }}-php-${{ matrix.php-version }}-${{ matrix.dependencies }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-php-${{ matrix.php-version }}-${{ matrix.dependencies }}-composer- + + - name: "Install dependencies" + run: "composer update --no-interaction --no-progress" + + - name: "Check coding standards" + run: "vendor/bin/php-cs-fixer fix --verbose --dry-run --diff" + + static-analysis: + name: "Static Analysis" + + runs-on: "ubuntu-latest" + + strategy: + matrix: + php-version: + - "7.4" + + steps: + - name: "Checkout" + uses: "actions/checkout@v2" + + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + coverage: "none" + php-version: "${{ matrix.php-version }}" + tools: cs2pr + + - name: "Get composer cache directory" + id: composercache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: "Cache dependencies" + uses: actions/cache@v2 + with: + path: ${{ steps.composercache.outputs.dir }} + key: ${{ runner.os }}-php-${{ matrix.php-version }}-${{ matrix.dependencies }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-php-${{ matrix.php-version }}-${{ matrix.dependencies }}-composer- + + - name: "Install dependencies" + run: "composer update --no-interaction --no-progress" + + - name: "Run static analysis" + run: "vendor/bin/phpstan analyse --no-progress --error-format=checkstyle | cs2pr" diff --git a/.php_cs b/.php_cs index e171c6c..c75dfc3 100644 --- a/.php_cs +++ b/.php_cs @@ -1,6 +1,6 @@ getFinder() ->in(__DIR__ . '/lib/Exception') ->in(__DIR__ . '/lib/Helper') diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7aaa153 --- /dev/null +++ b/Makefile @@ -0,0 +1,18 @@ +all: csfix static-analysis test + @echo "Done." + +vendor: composer.json + composer update + touch vendor + +.PHONY: csfix +csfix: vendor + vendor/bin/php-cs-fixer fix --verbose + +.PHONY: static-analysis +static-analysis: vendor + vendor/bin/phpstan analyse + +.PHONY: test +test: vendor + php -d zend.assertions=1 vendor/bin/phpunit diff --git a/composer.json b/composer.json index 87e07af..103d02c 100644 --- a/composer.json +++ b/composer.json @@ -10,19 +10,18 @@ } ], "require": { - "php": "^7.3" + "php": "^7.4 || ^8.0" }, "require-dev": { - "mikey179/vfsstream": "^1.6", - "phpoffice/phpspreadsheet": "^1.10", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^8.5", - "roave/security-advisories": "dev-master", - "slam/php-cs-fixer-extensions": "^1.19", - "slam/php-debug-r": "^1.6", - "slam/phpstan-extensions": "^4.0", - "thecodingmachine/phpstan-strict-rules": "^0.12" + "mikey179/vfsstream": "^1.6.8", + "phpoffice/phpspreadsheet": "^1.15.0", + "phpstan/phpstan": "^0.12.50", + "phpstan/phpstan-phpunit": "^0.12.16", + "phpunit/phpunit": "^9.4.2", + "slam/php-cs-fixer-extensions": "^2.0.0", + "slam/php-debug-r": "^1.6.1", + "slam/phpstan-extensions": "^5.0.2", + "thecodingmachine/phpstan-strict-rules": "^0.12.1" }, "autoload": { "psr-4": { diff --git a/lib/Helper/Column.php b/lib/Helper/Column.php index e7e20a4..683f208 100644 --- a/lib/Helper/Column.php +++ b/lib/Helper/Column.php @@ -6,25 +6,10 @@ final class Column implements ColumnInterface { - /** - * @var string - */ - private $key; - - /** - * @var string - */ - private $heading; - - /** - * @var int - */ - private $width; - - /** - * @var CellStyleInterface - */ - private $cellStyle; + private string $key; + private string $heading; + private int $width; + private CellStyleInterface $cellStyle; public function __construct(string $key, string $heading, int $width, CellStyleInterface $cellStyle) { diff --git a/lib/Helper/ColumnCollection.php b/lib/Helper/ColumnCollection.php index caddafb..ca9c1c4 100644 --- a/lib/Helper/ColumnCollection.php +++ b/lib/Helper/ColumnCollection.php @@ -11,7 +11,7 @@ final class ColumnCollection implements ColumnCollectionInterface /** * @var array */ - private $columns = []; + private array $columns = []; public function __construct(array $columns) { @@ -29,17 +29,15 @@ private function addColumn(ColumnInterface $column): void * @param string $offset * @param mixed $value */ - public function offsetSet($offset, $value) + public function offsetSet($offset, $value): void { throw new Exception\RuntimeException('Collection not editable'); } /** * @param string $offset - * - * @return bool */ - public function offsetExists($offset) + public function offsetExists($offset): bool { return isset($this->columns[$offset]); } @@ -47,17 +45,15 @@ public function offsetExists($offset) /** * @param string $offset */ - public function offsetUnset($offset) + public function offsetUnset($offset): void { throw new Exception\RuntimeException('Collection not editable'); } /** * @param string $offset - * - * @return null|mixed */ - public function offsetGet($offset) + public function offsetGet($offset): ?ColumnInterface { return $this->columns[$offset] ?? null; } diff --git a/lib/Helper/ColumnCollectionInterface.php b/lib/Helper/ColumnCollectionInterface.php index dc218a6..e8614b1 100644 --- a/lib/Helper/ColumnCollectionInterface.php +++ b/lib/Helper/ColumnCollectionInterface.php @@ -6,6 +6,9 @@ use ArrayAccess; +/** + * @extends ArrayAccess + */ interface ColumnCollectionInterface extends ArrayAccess { } diff --git a/lib/Helper/Table.php b/lib/Helper/Table.php index 8186a18..7fcf62b 100644 --- a/lib/Helper/Table.php +++ b/lib/Helper/Table.php @@ -11,90 +11,23 @@ final class Table implements Countable { - /** - * @var Worksheet - */ - private $activeSheet; - - /** - * @var null|int - */ - private $dataRowStart; - - /** - * @var int - */ - private $rowStart; - - /** - * @var int - */ - private $rowEnd; - - /** - * @var int - */ - private $rowCurrent; - - /** - * @var int - */ - private $columnStart; - - /** - * @var int - */ - private $columnEnd; - - /** - * @var int - */ - private $columnCurrent; - - /** - * @var string - */ - private $heading; - - /** - * @var Iterator - */ - private $data; - - /** - * @var null|ColumnCollectionInterface - */ - private $columnCollection; - - /** - * @var bool - */ - private $freezePanes = true; - - /** - * @var int - */ - private $fontSize = 8; - - /** - * @var null|int - */ - private $rowHeight; - - /** - * @var bool - */ - private $textWrap = false; - - /** - * @var null|array - */ - private $writtenColumnTitles; - - /** - * @var null|int - */ - private $count; + private Worksheet $activeSheet; + private ?int $dataRowStart = null; + private int $rowStart; + private int $rowEnd; + private int $rowCurrent; + private int $columnStart; + private int $columnEnd; + private int $columnCurrent; + private string $heading; + private Iterator $data; + private ?ColumnCollectionInterface $columnCollection = null; + private bool $freezePanes = true; + private int $fontSize = 8; + private ?int $rowHeight = null; + private bool $textWrap = false; + private ?array $writtenColumnTitles = null; + private ?int $count = null; public function __construct(Worksheet $activeSheet, int $row, int $column, string $heading, Iterator $data) { diff --git a/lib/Helper/TableWorkbook.php b/lib/Helper/TableWorkbook.php index 76a7770..bf9650b 100644 --- a/lib/Helper/TableWorkbook.php +++ b/lib/Helper/TableWorkbook.php @@ -11,25 +11,10 @@ final class TableWorkbook extends Excel\Pear\Writer\Workbook public const GREY_MEDIUM = 43; public const GREY_LIGHT = 42; - /** - * @var int - */ - private $rowsPerSheet = 60000; - - /** - * @var string - */ - private $emptyTableMessage = ''; - - /** - * @var CellStyle\Text - */ - private $styleIdentity; - - /** - * @var null|array - */ - private $formats; + private int $rowsPerSheet = 60000; + private string $emptyTableMessage = ''; + private CellStyle\Text $styleIdentity; + private ?array $formats; public function __construct(string $filename) { @@ -156,9 +141,9 @@ private function writeColumnsHeading(Table $table, array $row): void $width = 10; $newTitle = \ucwords(\str_replace('_', ' ', $title)); - if (isset($columnCollection) && isset($columnCollection[$title])) { - $width = $columnCollection[$title]->getWidth(); - $newTitle = $columnCollection[$title]->getHeading(); + if (null !== $columnCollection && null !== ($column = $columnCollection[$title])) { + $width = $column->getWidth(); + $newTitle = $column->getHeading(); } $table->getActiveSheet()->setColumn($table->getColumnCurrent(), $table->getColumnCurrent(), $width); diff --git a/phpstan.neon b/phpstan.neon index 6317caa..e239dd7 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -5,7 +5,6 @@ includes: - vendor/slam/phpstan-extensions/conf/thecodingmachine-rules.neon parameters: - checkGenericClassInNonGenericObjectType: false checkMissingIterableValueType: false paths: - lib/ @@ -13,9 +12,6 @@ parameters: excludes_analyse: - %currentWorkingDirectory%/lib/Pear/* ignoreErrors: - - - message: '#Method Slam\\Excel\\Helper\\ColumnCollection::offset.+ has no return typehint specified#' - path: %currentWorkingDirectory%/lib/Helper/ColumnCollection.php - message: '#Cannot call method \w+\(\) on PhpOffice\\PhpSpreadsheet\\Cell\\Cell\|null#' path: %currentWorkingDirectory%/tests/Helper/TableWorkbookTest.php diff --git a/phpunit.xml b/phpunit.xml index 9ff6949..f5398cf 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,16 +1,20 @@ + - - ./tests - - - - - ./lib - - + + + ./lib + + + + + + + ./tests + diff --git a/tests/Helper/TableTest.php b/tests/Helper/TableTest.php index ece053e..52fee65 100644 --- a/tests/Helper/TableTest.php +++ b/tests/Helper/TableTest.php @@ -21,7 +21,7 @@ final class TableTest extends TestCase private $activeSheet; /** - * @var ArrayIterator + * @var ArrayIterator */ private $data;