Skip to content

Commit

Permalink
refactor: Require PHP 8.0 (#194)
Browse files Browse the repository at this point in the history
* refactor: Require PHP 8.0; Bump all dependencies; Update workflow for PHP 8 requirement including newer versions PHP

* refactor: Update code to PHP 8.0 using rector; Upgrade progressbar to show current url

* refactor: Improving for PHP 8.0 support

* fix: Add missing entry in known endpoints to avoid losing ProjectProjectProgressReports
  • Loading branch information
DannyvdSluijs authored Dec 12, 2023
1 parent c941e4a commit 910700b
Show file tree
Hide file tree
Showing 22 changed files with 141 additions and 197 deletions.
41 changes: 19 additions & 22 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,6 @@ jobs:
strategy:
matrix:
include:
- php: 7.2
allow_fail: false
name: 'PHP 7.2 with latest deps'
- php: 7.2
allow_fail: false
composer_update_flags: '--prefer-lowest --prefer-stable'
name: 'PHP 7.2 with lowest stable deps'
- php: 7.3
allow_fail: false
name: 'PHP 7.3 with latest deps'
- php: 7.3
allow_fail: false
composer_update_flags: '--prefer-lowest --prefer-stable'
name: 'PHP 7.3 with lowest stable deps'
- php: 7.4
allow_fail: false
name: 'PHP 7.4 with latest deps'
- php: 7.4
allow_fail: false
composer_update_flags: '--prefer-lowest --prefer-stable'
name: 'PHP 7.4 with lowest stable deps'
- php: 8.0
allow_fail: false
php_ini: 'xdebug.coverage_enable=On'
Expand All @@ -52,11 +31,29 @@ jobs:
composer_update_flags: '--prefer-lowest --prefer-stable'
php_ini: 'xdebug.coverage_enable=On'
name: 'PHP 8.1 with lowest stable deps'
- php: 8.2
allow_fail: true
php_ini: 'xdebug.coverage_enable=On'
name: 'PHP 8.2 with latest deps'
- php: 8.2
allow_fail: true
composer_update_flags: '--prefer-lowest --prefer-stable'
php_ini: 'xdebug.coverage_enable=On'
name: 'PHP 8.2 with lowest stable deps'
- php: 8.3
allow_fail: true
php_ini: 'xdebug.coverage_enable=On'
name: 'PHP 8.3 with latest deps'
- php: 8.3
allow_fail: true
composer_update_flags: '--prefer-lowest --prefer-stable'
php_ini: 'xdebug.coverage_enable=On'
name: 'PHP 8.3 with lowest stable deps'

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- name: Validate composer.json and composer.lock
run: composer validate
Expand Down
27 changes: 17 additions & 10 deletions MetaDataTool/Command/MetaDataBuilderCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@
use MetaDataTool\Crawlers\MainPageCrawler;
use MetaDataTool\Enum\KnownEntities;
use MetaDataTool\JsonFileWriter;
use MetaDataTool\PageRegistry;
use MetaDataTool\ValueObjects\Endpoint;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

class MetaDataBuilderCommand extends Command
{
private const MAINPAGE = 'https://start.exactonline.nl/docs/HlpRestAPIResources.aspx';
private const MAIN_PAGE = 'https://start.exactonline.nl/docs/HlpRestAPIResources.aspx';
protected static $defaultName = 'run';


protected function configure(): void
{
$this
Expand Down Expand Up @@ -52,22 +52,29 @@ protected function execute(InputInterface $input, OutputInterface $output): int
die(1);
}

$io->info(['Scanning main page', self::MAINPAGE]);
$mainPageCrawler = new MainPageCrawler(self::MAINPAGE);
$io->info(['Scanning main page', self::MAIN_PAGE]);
$mainPageCrawler = new MainPageCrawler(self::MAIN_PAGE);
$pages = $mainPageCrawler->run();
foreach (KnownEntities::keys() as $entity) {
$pages->add('https://start.exactonline.nl/docs/HlpRestAPIResourcesDetails.aspx?name=' . $entity);
}

$io->info('Scanning entity pages');
$io->progressStart($pages->count());
ProgressBar::setFormatDefinition('custom', ' %current%/%max% -- %message% (%url%)');
$progressBar = $io->createProgressBar($pages->count());
$progressBar->setFormat('custom');
$progressBar->setMessage('Processing documentation');
$progressBar->start();

$config = new EndpointCrawlerConfig(true);
$endpoints = (new EndpointCrawler($config, $pages))
->run(static function() use ($io): void {
$io->progressAdvance(1);
->run(static function(Endpoint $endpoint) use ($progressBar): void {
$progressBar->advance(1);
$progressBar->setMessage($endpoint->getDocumentation(), 'url');
});
$io->progressFinish();
$progressBar->finish();
$progressBar->setMessage('');
$io->newLine(2);

$io->info('Creating meta data file');
$writer = new JsonFileWriter($this->getFullDestinationPath($destination));
Expand All @@ -79,7 +86,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int

private function getFullDestinationPath(string $destination): string
{
if (strpos($destination, DIRECTORY_SEPARATOR) === 0 || strpos($destination, '.') === 0) {
if (str_starts_with($destination, DIRECTORY_SEPARATOR) || str_starts_with($destination, '.')) {
return $destination;
}

Expand Down
6 changes: 1 addition & 5 deletions MetaDataTool/Config/EndpointCrawlerConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,8 @@

class EndpointCrawlerConfig
{
/** @var bool */
private $queueDiscoveredLinks;

public function __construct(bool $queueDiscoveredLinks)
public function __construct(private bool $queueDiscoveredLinks)
{
$this->queueDiscoveredLinks = $queueDiscoveredLinks;
}

public function shouldQueueDiscoveredLinks(): bool
Expand Down
40 changes: 20 additions & 20 deletions MetaDataTool/Crawlers/EndpointCrawler.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,12 @@ class EndpointCrawler
private const BASE_URL = 'https://start.exactonline.nl/docs/';
private const ATTRIBUTE_HEADER_XPATH = '//table[@id="referencetable"]/tr[1]';
private const ATTRIBUTE_ROWS_XPATH = '//table[@id="referencetable"]/tr[position()>1]';
private PageRegistry $pagesToVisit;
private PageRegistry $visitedPages;
private ?Crawler $domCrawler = null;

/** @var EndpointCrawlerConfig */
private $config;
/** @var PageRegistry */
private $pagesToVisit;
/** @var PageRegistry */
private $visitedPages;
/** @var Crawler */
private $domCrawler;

public function __construct(EndpointCrawlerConfig $config, ?PageRegistry $pagesToVisit = null)
public function __construct(private EndpointCrawlerConfig $config, ?PageRegistry $pagesToVisit = null)
{
$this->config = $config;
$this->pagesToVisit = $pagesToVisit ?? $this->createDefaultPagesToVisit();
$this->visitedPages = new PageRegistry();
}
Expand Down Expand Up @@ -83,7 +76,7 @@ private function crawlWebPage(string $url): ?Endpoint
$scope = $this->domCrawler->filterXPath('//*[@id="scope"]')->first()->text();
try {
$uri = $this->domCrawler->filterXPath('//*[@id="serviceUri"]')->first()->text();
} catch (\Exception $exception) {
} catch (\Exception) {
return null;
}
$supportedMethodsCrawler = $this->domCrawler->filterXPath('//input[@name="supportedmethods"]');
Expand All @@ -107,9 +100,7 @@ private function crawlWebPage(string $url): ?Endpoint
return null;
}

$columns = array_map(static function ($n) {
return explode(' ', $n->nodeValue)[0];
}, $header->children()->getIterator()->getArrayCopy());
$columns = array_map(static fn($n) => explode(' ', $n->nodeValue)[0], $header->children()->getIterator()->getArrayCopy());

$propertyRowParserConfig = new PropertyRowParserConfig(
array_search('Type', $columns, true) + 1,
Expand All @@ -122,7 +113,7 @@ private function crawlWebPage(string $url): ?Endpoint

$goodToKnows = $this->domCrawler->filterXPath('//*[@id="goodToKnow"]');
$deprecationMessage = 'This endpoint is redundant and is going to be removed.';
$isDeprecated = $goodToKnows->count() > 0 && strpos($goodToKnows->first()->text(), $deprecationMessage) !== false;
$isDeprecated = $goodToKnows->count() > 0 && str_contains($goodToKnows->first()->text(), $deprecationMessage);
return new Endpoint(
$endpoint,
$url,
Expand All @@ -137,7 +128,16 @@ private function crawlWebPage(string $url): ?Endpoint

private function fetchHtmlFromUrl(string $url): string
{
$html = file_get_contents($url);
[,$basename] = explode('=', $url);
$filename = sys_get_temp_dir() . '/exact-online-meta-data-tool-' . strtolower($basename) . '.html';

if (!file_exists($filename)) {
$html = file_get_contents($url);
file_put_contents($filename, $html);
} else {
$html = file_get_contents($filename);
}

$this->visitedPages->add($url);

if ($html === false) {
Expand Down Expand Up @@ -166,16 +166,16 @@ private function getPropertyRowParser(PropertyRowParserConfig $config): \Closure
if ($name === 'ID') {
$httpMethods = $httpMethods->addDelete();
}
if (strpos($class, 'hideput') === false && strpos($class, 'showget') === false) {
if (!str_contains($class, 'hideput') && !str_contains($class, 'showget')) {
$httpMethods = $httpMethods->addPut();
}
if (strpos($class, 'hidepost') === false && strpos($class, 'showget') === false) {
if (!str_contains($class, 'hidepost') && !str_contains($class, 'showget')) {
$httpMethods = $httpMethods->addPost();
}
if ($name === 'ID') {
$httpMethods = HttpMethodMask::all();
}
$hidden = strpos($node->attr('class') ?? '', 'hiderow') !== false;
$hidden = str_contains($node->attr('class') ?? '', 'hiderow');
$mandatory = strtolower(trim($node->filterXpath("//td[{$config->getMandatoryColumnIndex()}]")->text())) === 'true';

return new Property($name, $type, $description, $primaryKey, $httpMethods, $hidden, $mandatory);
Expand Down
8 changes: 1 addition & 7 deletions MetaDataTool/Crawlers/MainPageCrawler.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,7 @@

class MainPageCrawler
{
/** @var string */
private $mainPage;

public function __construct(string $mainPage)
{
$this->mainPage = $mainPage;
}
public function __construct(private string $mainPage) {}

public function run(): PageRegistry
{
Expand Down
1 change: 1 addition & 0 deletions MetaDataTool/Enum/KnownEntities.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ class KnownEntities extends Enum
private const ProjectProjectHourBudgets = 'ProjectProjectHourBudgets';
private const ProjectProjectPlanning = 'ProjectProjectPlanning';
private const ProjectProjectPlanningRecurring = 'ProjectProjectPlanningRecurring';
private const ProjectProjectProgressReports = 'ProjectProjectProgressReports';
private const ProjectProjectRestrictionEmployees = 'ProjectProjectRestrictionEmployees';
private const ProjectProjectRestrictionItems = 'ProjectProjectRestrictionItems';
private const ProjectProjectRestrictionRebillings = 'ProjectProjectRestrictionRebillings';
Expand Down
9 changes: 2 additions & 7 deletions MetaDataTool/JsonFileWriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,17 @@ class JsonFileWriter
{
private const FILE_NAME = '/meta-data.json';

/** @var string */
private $path;

/**
* JsonFileWriter constructor.
* @param string $path
*/
public function __construct(string $path)
public function __construct(private string $path)
{
$this->path = $path;
$this->ensureDirectoryAvailability($path);
}

public function write(EndpointCollection $endpoints): void
{
file_put_contents($this->getFullFileName(), json_encode($endpoints, JSON_PRETTY_PRINT));
file_put_contents($this->getFullFileName(), json_encode($endpoints, JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT));
}

public function getFullFileName(): string
Expand Down
2 changes: 1 addition & 1 deletion MetaDataTool/PageRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
class PageRegistry implements \Countable, \IteratorAggregate
{
/** @var string[] */
private $pages = [];
private array $pages;

public function __construct(string ...$pages)
{
Expand Down
44 changes: 9 additions & 35 deletions MetaDataTool/ValueObjects/Endpoint.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,42 +8,16 @@

class Endpoint implements JsonSerializable
{
/** @var string */
private $endpoint;
/** @var string */
private $documentation;
/** @var string */
private $scope;
/** @var string */
private $uri;
/** @var HttpMethodMask */
private $supportedHttpMethods;
/** @var string */
private $example;
/** @var PropertyCollection */
private $properties;
/** @var bool */
private $isDeprecated;

public function __construct(
string $endpoint,
string $documentation,
string $scope,
string $uri,
HttpMethodMask $supportedHttpMethods,
string $example,
PropertyCollection $properties,
bool $isDeprecated = false
) {
$this->endpoint = $endpoint;
$this->documentation = $documentation;
$this->scope = $scope;
$this->uri = $uri;
$this->supportedHttpMethods = $supportedHttpMethods;
$this->example = $example;
$this->properties = $properties;
$this->isDeprecated = $isDeprecated;
}
private string $endpoint,
private string $documentation,
private string $scope,
private string $uri,
private HttpMethodMask $supportedHttpMethods,
private string $example,
private PropertyCollection $properties,
private bool $isDeprecated = false
) {}

public function getEndpoint(): string
{
Expand Down
6 changes: 1 addition & 5 deletions MetaDataTool/ValueObjects/HttpMethodMask.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,8 @@ class HttpMethodMask implements JsonSerializable
private const DELETE = 8;
private const ALL = 15;

/** @var int */
private $mask;

private function __construct(int $mask)
private function __construct(private int $mask)
{
$this->mask = $mask;
}

public static function none(): self
Expand Down
Loading

0 comments on commit 910700b

Please sign in to comment.