antecedent/patchwork

Patching function that may be both internal and user-defined

Stadly opened this issue · 1 comments

I am writing a library that use pspell for some functionality, but pspell is not a requirement. Therefore I do not want to assume that pspell is available, and particularly not in my tests. I am patching the functions pspell_new and pspell_check in my tests.

Since the functions may not be available, I define the functions if they do not exist:

if (!function_exists('pspell_new')) {
    function pspell_new(string $language, string $spelling = '', string $jargon = '', string $encoding = '', int $mode = 0): int
    {
        return -1;
    }
}

if (!function_exists('pspell_check')) {
    function pspell_check(int $dictionary_link, string $word): bool
    {
        return false;
    }
}

This issue is what should patchwork.json look like?

When pspell is available, it works when patchwork.json looks like this:

{
    "redefinable-internals": [
        "pspell_new",
        "pspell_check"
    ]
}

When pspell is not available, however, patchwork.json must look like this:

{
}

But since I don't know whether pspell will be available on the system, I cannot determine what patchwork.json should look like. How can I patch functions that may either be internal or user-defined?

I have a similar issue depending on what PHP modules are/not involved in local environment vs CI/CD build server where the tests may run. In particular the php_ldap module and trying to provide stubs for ldap_bind, ldap_connect, etc.

The closest I have come while keeping the patchwork.json with contents is have my bootstrap.php file include a function exists check before defining a version that patching could override. But that still nets a "Patchwork\Exceptions\DefinedTooEarly: The file that defines ldap_bind() was included earlier than Patchwork." error.

Might there be some config option that can be set to let internal functions that do not exist still be defined via patchwork?