dirtsimple / postmark

Sync Wordpress Pages and Posts (even custom post types + fields) from static Markdown + YAML files
MIT License
29 stars 7 forks source link

PHP version upgrade: how to install on a modern PHP 8.1.2? #4

Open vadimkantorov opened 7 months ago

vadimkantorov commented 7 months ago

I've tried installing postmark using wp-cli and got an error about the supported PHP version. Is it possible to use the postmark plugin with php 8.1.2? Thank you!

$ php wp-cli.phar package install dirtsimple/postmark

Installing package dirtsimple/postmark (dev-master)
Updating /home/vadimkantorov/.wp-cli/packages/composer.json to require the package...
Registering https://github.com/dirtsimple/postmark.git as a VCS repository...
Using Composer to install the package...
---
Loading composer repositories with package information
Found 403 package versions referenced in your dependency graph. 300 (74%) were optimized away.
Updating dependencies
Generating rules
Resolving dependencies through SAT
Looking at all rules.

Dependency resolution completed in 0.001 seconds
Your requirements could not be resolved to an installable set of packages.
Problem 1
    - Root composer.json requires dirtsimple/postmark dev-master -> satisfiable by dirtsimple/postmark[dev-master].
    - dirtsimple/postmark dev-master requires php ^7.1 -> your php version (8.1.2) does not satisfy that requirement.
Running update with --no-dev does not mean require-dev is ignored, it just means the packages will not be installed. If dev requirements are blocking the update you have to resolve those problems.
---
Error: Package installation failed (Composer return code 2).
Reverted composer.json.
vadimkantorov commented 7 months ago

What I did is I git clone https://github.com/dirtsimple/postmark/, then replaced composer.json by the following relaxed version:

{
    "name": "dirtsimple/postmark",
    "description": "Sync WP content from Markdown files",
    "type": "wp-cli-package",
    "homepage": "https://github.com/dirtsimple/postmark/",
    "license": "MIT",
    "authors": [
        {
            "name": "PJ Eby",
            "homepage": "https://github.com/pjeby"
        }
    ],
    "keywords": [
        "markdown",
        "wordpress",
        "wp",
        "wp-cli",
        "yaml",
        "front-matter",
        "content-management",
        "configuration-management",
        "static-site-generator",
        "yaml front matter"
    ],
    "minimum-stability": "dev",
    "prefer-stable": true,
    "autoload": {
        "files": [ "command.php" ],
        "psr-4": {
            "dirtsimple\\Postmark\\": "src/"
        }
    },
    "require": {
        "dirtsimple/clean-yaml": "^0.1",
        "dirtsimple/imposer": "dev-master",
        "wp-cli/wp-cli": "*",
        "wp-cli/entity-command": "*",
        "rarst/wpdatetime": "*",
        "league/commonmark": "*",
        "league/commonmark-ext-smartpunct": "*",
        "league/commonmark-ext-strikethrough": "*",
        "league/commonmark-ext-table": "*",
        "webuni/commonmark-attributes-extension": "*",
        "twig/twig": "*",
        "symfony/yaml": "*",
        "php" : "*"
    }
}

and then ran php wp-cli.phar package install ./postmark - which installed it successfully.

vadimkantorov commented 7 months ago

This printed:

Package league/commonmark-ext-smartpunct is abandoned, you should avoid using it. Use league/commonmark instead.
Package league/commonmark-ext-strikethrough is abandoned, you should avoid using it. Use league/commonmark instead.
Package league/commonmark-ext-table is abandoned, you should avoid using it. Use league/commonmark instead.
Package rarst/wpdatetime is abandoned, you should avoid using it. No replacement was suggested.
Package webuni/commonmark-attributes-extension is abandoned, you should avoid using it. Use league/commonmark instead.

suggesting that the league/commonmark-ext-table and other packages is deprecated:

vadimkantorov commented 7 months ago

When I run php wp-cli.phar postmark tree ./_posts, I get the following error suggesting that the Table extension is not available.

If postmark isn't updated enough, maybe could you suggest a replacement? Thank you very much!

PHP Fatal error:  Uncaught ReflectionException: Class "League\CommonMark\Ext\Table\TableExtension" does not exist in /mnt/c/Users/vadim/wpssg/postmark/src/Formatter.php:48
Stack trace:
#0 /mnt/c/Users/vadim/wpssg/postmark/src/Formatter.php(48): ReflectionClass->__construct()
#1 /mnt/c/Users/vadim/wpssg/postmark/src/Formatter.php(40): dirtsimple\Postmark\Formatter::addExtensions()
#2 /mnt/c/Users/vadim/wpssg/postmark/src/Formatter.php(16): dirtsimple\Postmark\Formatter::formatter()
#3 /mnt/c/Users/vadim/wpssg/postmark/src/MarkdownFile.php(97): dirtsimple\Postmark\Formatter::format()
#4 /mnt/c/Users/vadim/wpssg/postmark/src/PostImporter.php(88): dirtsimple\Postmark\MarkdownFile->html()
#5 /mnt/c/Users/vadim/wpssg/postmark/src/PostImporter.php(180): dirtsimple\Postmark\PostImporter->syncField()
#6 /mnt/c/Users/vadim/wpssg/postmark/src/PostImporter.php(108): dirtsimple\Postmark\PostImporter->_syncinfo_content()
#7 /mnt/c/Users/vadim/wpssg/postmark/src/PostImporter.php(28): dirtsimple\Postmark\PostImporter->sync()
#8 /mnt/c/Users/vadim/wpssg/postmark/src/Kind.php(83): dirtsimple\Postmark\PostImporter::sync_doc()
#9 [internal function]: dirtsimple\Postmark\KindImpl->import()
#10 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/WatchedPromise.php(62): Generator->current()
#11 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/WatchedPromise.php(83): dirtsimple\imposer\WatchedPromise->dirtsimple\imposer\{closure}()
#12 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/Promise.php(52): dirtsimple\imposer\WatchedPromise->spawn()
#13 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/Promise.php(28): dirtsimple\imposer\Promise::spawn()
#14 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/WatchedPromise.php(62): dirtsimple\imposer\Promise::interpret()
#15 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/WatchedPromise.php(83): dirtsimple\imposer\WatchedPromise->dirtsimple\imposer\{closure}()
#16 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/WatchedPromise.php(38): dirtsimple\imposer\WatchedPromise->spawn()
#17 /mnt/c/Users/vadim/wpssg/postmark/src/Database.php(42): dirtsimple\imposer\WatchedPromise->call()
#18 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/Pool.php(20): dirtsimple\Postmark\Database->dirtsimple\Postmark\{closure}()
#19 /mnt/c/Users/vadim/wpssg/postmark/src/Database.php(82): dirtsimple\imposer\Pool->offsetGet()
#20 /mnt/c/Users/vadim/wpssg/postmark/src/PostmarkCommand.php(241): dirtsimple\Postmark\Database->sync()
#21 [internal function]: dirtsimple\Postmark\PostmarkCommand->sync_docs()
#22 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/WatchedPromise.php(62): Generator->current()
#23 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/WatchedPromise.php(83): dirtsimple\imposer\WatchedPromise->dirtsimple\imposer\{closure}()
#24 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/Promise.php(52): dirtsimple\imposer\WatchedPromise->spawn()
#25 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/Promise.php(28): dirtsimple\imposer\Promise::spawn()
#26 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/WatchedPromise.php(62): dirtsimple\imposer\Promise::interpret()
#27 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/WatchedPromise.php(83): dirtsimple\imposer\WatchedPromise->dirtsimple\imposer\{closure}()
#28 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/Promise.php(52): dirtsimple\imposer\WatchedPromise->spawn()
#29 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/Promise.php(28): dirtsimple\imposer\Promise::spawn()
#30 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/Task.php(113): dirtsimple\imposer\Promise::interpret()
#31 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/Task.php(92): dirtsimple\imposer\Task->run_next_step()
#32 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/Scheduler.php(76): dirtsimple\imposer\Task->run()
#33 [internal function]: dirtsimple\imposer\Scheduler->run()
#34 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/Imposer.php(66): call_user_func_array()
#35 [internal function]: dirtsimple\imposer\Imposer->__call()
#36 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/Imposer.php(61): call_user_func_array()
#37 /mnt/c/Users/vadim/wpssg/postmark/src/PostmarkCommand.php(165): dirtsimple\imposer\Imposer::__callStatic()
#38 [internal function]: dirtsimple\Postmark\PostmarkCommand->tree()
#39 phar:///mnt/c/Users/vadim/wpssg/wp-cli.phar/vendor/wp-cli/wp-cli/php/WP_CLI/Dispatcher/CommandFactory.php(100): call_user_func()
#40 [internal function]: WP_CLI\Dispatcher\CommandFactory::WP_CLI\Dispatcher\{closure}()
#41 phar:///mnt/c/Users/vadim/wpssg/wp-cli.phar/vendor/wp-cli/wp-cli/php/WP_CLI/Dispatcher/Subcommand.php(488): call_user_func()
#42 phar:///mnt/c/Users/vadim/wpssg/wp-cli.phar/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(436): WP_CLI\Dispatcher\Subcommand->invoke()
#43 phar:///mnt/c/Users/vadim/wpssg/wp-cli.phar/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(459): WP_CLI\Runner->run_command()
#44 phar:///mnt/c/Users/vadim/wpssg/wp-cli.phar/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(1284): WP_CLI\Runner->run_command_and_exit()
#45 phar:///mnt/c/Users/vadim/wpssg/wp-cli.phar/vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LaunchRunner.php(28): WP_CLI\Runner->start()
#46 phar:///mnt/c/Users/vadim/wpssg/wp-cli.phar/vendor/wp-cli/wp-cli/php/bootstrap.php(83): WP_CLI\Bootstrap\LaunchRunner->process()
#47 phar:///mnt/c/Users/vadim/wpssg/wp-cli.phar/vendor/wp-cli/wp-cli/php/wp-cli.php(32): WP_CLI\bootstrap()
#48 phar:///mnt/c/Users/vadim/wpssg/wp-cli.phar/php/boot-phar.php(20): include('...')
#49 /mnt/c/Users/vadim/wpssg/wp-cli.phar(4): include('...')
#50 {main}
  thrown in /mnt/c/Users/vadim/wpssg/postmark/src/Formatter.php on line 48
Fatal error: Uncaught ReflectionException: Class "League\CommonMark\Ext\Table\TableExtension" does not exist in /mnt/c/Users/vadim/wpssg/postmark/src/Formatter.php:48
Stack trace:
#0 /mnt/c/Users/vadim/wpssg/postmark/src/Formatter.php(48): ReflectionClass->__construct()
#1 /mnt/c/Users/vadim/wpssg/postmark/src/Formatter.php(40): dirtsimple\Postmark\Formatter::addExtensions()
#2 /mnt/c/Users/vadim/wpssg/postmark/src/Formatter.php(16): dirtsimple\Postmark\Formatter::formatter()
#3 /mnt/c/Users/vadim/wpssg/postmark/src/MarkdownFile.php(97): dirtsimple\Postmark\Formatter::format()
#4 /mnt/c/Users/vadim/wpssg/postmark/src/PostImporter.php(88): dirtsimple\Postmark\MarkdownFile->html()
#5 /mnt/c/Users/vadim/wpssg/postmark/src/PostImporter.php(180): dirtsimple\Postmark\PostImporter->syncField()
#6 /mnt/c/Users/vadim/wpssg/postmark/src/PostImporter.php(108): dirtsimple\Postmark\PostImporter->_syncinfo_content()
#7 /mnt/c/Users/vadim/wpssg/postmark/src/PostImporter.php(28): dirtsimple\Postmark\PostImporter->sync()
#8 /mnt/c/Users/vadim/wpssg/postmark/src/Kind.php(83): dirtsimple\Postmark\PostImporter::sync_doc()
#9 [internal function]: dirtsimple\Postmark\KindImpl->import()
#10 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/WatchedPromise.php(62): Generator->current()
#11 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/WatchedPromise.php(83): dirtsimple\imposer\WatchedPromise->dirtsimple\imposer\{closure}()
#12 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/Promise.php(52): dirtsimple\imposer\WatchedPromise->spawn()
#13 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/Promise.php(28): dirtsimple\imposer\Promise::spawn()
#14 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/WatchedPromise.php(62): dirtsimple\imposer\Promise::interpret()
#15 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/WatchedPromise.php(83): dirtsimple\imposer\WatchedPromise->dirtsimple\imposer\{closure}()
#16 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/WatchedPromise.php(38): dirtsimple\imposer\WatchedPromise->spawn()
#17 /mnt/c/Users/vadim/wpssg/postmark/src/Database.php(42): dirtsimple\imposer\WatchedPromise->call()
#18 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/Pool.php(20): dirtsimple\Postmark\Database->dirtsimple\Postmark\{closure}()
#19 /mnt/c/Users/vadim/wpssg/postmark/src/Database.php(82): dirtsimple\imposer\Pool->offsetGet()
#20 /mnt/c/Users/vadim/wpssg/postmark/src/PostmarkCommand.php(241): dirtsimple\Postmark\Database->sync()
#21 [internal function]: dirtsimple\Postmark\PostmarkCommand->sync_docs()
#22 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/WatchedPromise.php(62): Generator->current()
#23 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/WatchedPromise.php(83): dirtsimple\imposer\WatchedPromise->dirtsimple\imposer\{closure}()
#24 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/Promise.php(52): dirtsimple\imposer\WatchedPromise->spawn()
#25 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/Promise.php(28): dirtsimple\imposer\Promise::spawn()
#26 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/WatchedPromise.php(62): dirtsimple\imposer\Promise::interpret()
#27 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/WatchedPromise.php(83): dirtsimple\imposer\WatchedPromise->dirtsimple\imposer\{closure}()
#28 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/Promise.php(52): dirtsimple\imposer\WatchedPromise->spawn()
#29 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/Promise.php(28): dirtsimple\imposer\Promise::spawn()
#30 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/Task.php(113): dirtsimple\imposer\Promise::interpret()
#31 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/Task.php(92): dirtsimple\imposer\Task->run_next_step()
#32 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/Scheduler.php(76): dirtsimple\imposer\Task->run()
#33 [internal function]: dirtsimple\imposer\Scheduler->run()
#34 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/Imposer.php(66): call_user_func_array()
#35 [internal function]: dirtsimple\imposer\Imposer->__call()
#36 /home/vadimkantorov/.wp-cli/packages/vendor/dirtsimple/imposer/src/Imposer.php(61): call_user_func_array()
#37 /mnt/c/Users/vadim/wpssg/postmark/src/PostmarkCommand.php(165): dirtsimple\imposer\Imposer::__callStatic()
#38 [internal function]: dirtsimple\Postmark\PostmarkCommand->tree()
#39 phar:///mnt/c/Users/vadim/wpssg/wp-cli.phar/vendor/wp-cli/wp-cli/php/WP_CLI/Dispatcher/CommandFactory.php(100): call_user_func()
#40 [internal function]: WP_CLI\Dispatcher\CommandFactory::WP_CLI\Dispatcher\{closure}()
#41 phar:///mnt/c/Users/vadim/wpssg/wp-cli.phar/vendor/wp-cli/wp-cli/php/WP_CLI/Dispatcher/Subcommand.php(488): call_user_func()
#42 phar:///mnt/c/Users/vadim/wpssg/wp-cli.phar/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(436): WP_CLI\Dispatcher\Subcommand->invoke()
#43 phar:///mnt/c/Users/vadim/wpssg/wp-cli.phar/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(459): WP_CLI\Runner->run_command()
#44 phar:///mnt/c/Users/vadim/wpssg/wp-cli.phar/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(1284): WP_CLI\Runner->run_command_and_exit()
#45 phar:///mnt/c/Users/vadim/wpssg/wp-cli.phar/vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LaunchRunner.php(28): WP_CLI\Runner->start()
#46 phar:///mnt/c/Users/vadim/wpssg/wp-cli.phar/vendor/wp-cli/wp-cli/php/bootstrap.php(83): WP_CLI\Bootstrap\LaunchRunner->process()
#47 phar:///mnt/c/Users/vadim/wpssg/wp-cli.phar/vendor/wp-cli/wp-cli/php/wp-cli.php(32): WP_CLI\bootstrap()
#48 phar:///mnt/c/Users/vadim/wpssg/wp-cli.phar/php/boot-phar.php(20): include('...')
#49 /mnt/c/Users/vadim/wpssg/wp-cli.phar(4): include('...')
#50 {main}
  thrown in /mnt/c/Users/vadim/wpssg/postmark/src/Formatter.php on line 48
Error: There has been a critical error on this website.Learn more about troubleshooting WordPress. There has been a critical error on this website.
pjeby commented 7 months ago

It looks like in the current league/commonmark, the extension namespace is League\CommonMark\Extension\Table. If you look at https://github.com/dirtsimple/postmark/blob/master/src/Formatter.php#L29 you'll see that the configuration used is passed through the postmark_formatter_config hook, so you can use that hook to change the extension paths.

If you visit the github repos of the various deprecated packages, they give the new paths for the extensions. I don't know if that will entirely fix your problem, but that would appear to be the next step.

At the moment, I am still supporting PHP 7.1 for some sites, so I can't really switch to the newer league/commonmark version yet as it requires 7.4 as a minimum. But patches to improve 8.x compatibility that don't break 7.1 (or older WP versions) are welcome. If something that's necessary is incompatible, I suppose I could make an alternate dev branch, but I'd prefer not to if possible.

pjeby commented 7 months ago

Also, it looks like you might be able to put back the requirement for league/commonmark to be 1.x, as the newer 1.x versions support both PHP 7.1 and 8.x, which means the result might be releasable on the master branch here. In general, I would suggest not using * versions but keeping the ones postmark specifies unless absolutely necessary to upgrade. In some cases (e.g. commonmark) you may be getting versions that postmark is just not compatible with.

vadimkantorov commented 7 months ago

Thanks for your feedback! I'll try to figure it out. I absolutely have no PHP experience though, so it might be a bit rough.

I've also tried keeping the commonmark-related packages intact. When I use

        "league/commonmark": "^1.0",
        "league/commonmark-ext-smartpunct": "^1.1",
        "league/commonmark-ext-strikethrough": "^1.0",
        "league/commonmark-ext-table": "^2.1",
        "webuni/commonmark-attributes-extension": "^1.0",

I get

Problem 1
    - league/commonmark-ext-smartpunct[v1.1.0, v1.2.0, 1.3.x-dev] require php ^7.1 -> your php version (8.1.2) does not satisfy that requirement.
    - dirtsimple/postmark dev-master requires league/commonmark-ext-smartpunct ^1.1 -> satisfiable by league/commonmark-ext-smartpunct[v1.1.0, v1.2.0, 1.3.x-dev].
    - Root composer.json requires dirtsimple/postmark dev-main || dev-master || dev-trunk -> satisfiable by dirtsimple/postmark[dev-master].

Indeed, the latest release of smartpunct before deprecation still requires php 7.1, as it was deprecated in 2020

vadimkantorov commented 7 months ago

I guess, the firs question might be: is it possible to build postmark without these commonmark extensions? E.g. it seems that smartpunct was upstreamed the main league/commmonmark repo

vadimkantorov commented 7 months ago

It appears that one now must use this https://commonmark.thephpleague.com/2.4/extensions/github-flavored-markdown/ instead of the legacy smartpunct/strikethrough/table extensions

vadimkantorov commented 7 months ago

And the attributes extension was also upstreamed to https://commonmark.thephpleague.com/2.4/extensions/attributes/

vadimkantorov commented 7 months ago

The mainline commonmark 2.4 supports "php": "^7.4 || ^8.0", https://github.com/thephpleague/commonmark/blob/2.4/composer.json#L24 - not sure if I could use on the newest php 8.1.2?

vadimkantorov commented 7 months ago

I commented out the e

you'll see that the configuration used is passed through the postmark_formatter_config hook, so you can use that hook to change the extension paths.

So far I just patched out this method and the sync command worked!

vadimkantorov commented 7 months ago

If you are interested, I'm documenting here https://github.com/vadimkantorov/wpssg commands to turn WordPress into a SSG and being able to run in in GitHub Actions, similar to Jekyll (this is useful for some porting scenarios of simple content-only blogs)

pjeby commented 7 months ago

I believe that all you really need to do is upgrade league/commonmark to 1.6, change the paths for the extensions, and change the PHP version required to be appropriate, and it would probably be compatible with PHP 7.1 - 8.1. I do plan to give that a try at some point myself, and if I do I will update the repo. Just not sure when I'll have the time to dive into it.