Skip to content

Get rid of tools/ #287

@thekid

Description

@thekid

Scope of Change

This RFC suggests removing the special case handling necessary for the tools/ directory, e.g. in the build system, in possible future composer integration and so on.

Rationale

Make it easier to setup and embed the XP Framework.

Functionality

a) Setup

The goal is to remove special-case handling in build tools like our own xpbuild infrastructure and add-ons like the Maven build.

Current New
1. User invokes xp runner with class as arg 1. -~-
2. xp runner starts php /path/to/xp/tools/class-main.php. 2. xp runner starts php /path/to/runners/class-main.php
3. This installs CLI specific handling 3. -~-
4. Then, lang.base.php is loaded 4. The class path from ./*.pth is searched for __xp.php, which contains the bootstrap code
5. The class path is compiled by scanning all *.pth files in use= ... and the current directory 5. The rest of the paths from use=... inside xp.ini is compiled to an include path and searched for __xp.php if not previously found.
6. The bootstrap() method is invoked 6. The bootstrapping code is executed
7. The class from the args is loaded 7. -~-
8. Its static main method is invoked with the rest of the args 8. -~-
9. Exceptions are caught. 9. -~-
10. The return value from main is returned as exit code 10. -~-

This way, we can also support a local XP Framework requirement other than the per-system/per-user installation:

Path files in . XP Framework version used
(no files) The one in use=...
A single file class.pth, with lib/mustache.xar and src/main/php -~-
A single file glue.pth with vendor/xp-framework/xp-core-6.0.0.xar The one in the xar file
Two files: class.pth (as above) and glue.pth (as above) -~-

b) Via Apache

As a special case for running the XP Framework without runners but with the same entry point behavior, the following is necessary:

<VirtualHost ...>
  DocumentRoot ...

  RewriteEngine on
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^.*$ /web-main.php [PT,L]
</VirtualHost>

Now either use aliasing, symlink the web-main.php, or install the runners into the document root

ScriptAlias /web-main.php /path/to/global/xp/runners/setup/web-main.php

The framework version is determined by checking the *.pth files in the web root (defaults to {DOCUMENT_ROOT}/..). If you depend on xp-framework/core, this will be sufficient. This is the suggested way of doing it.

For legacy projects not depending on xp-framework/core, you can supply include_path=".:/path/to/xp/version" to provide a use path and use a double path separator for additional includes (e.g. include_path=".:/path/to/xp/version::/path/to/additional/includes:/path/to/even/more/includes")

c) Embedding

The goal is to be able to embed the XP Framework; or parts of it, in other applications. People may be interested in a userland MSSQL/Sybase protocol implementation instead of having to bug their devops to compile that for them; which is quite a hassle.

Since modern PHP applications are installed via Composer nowadays, we would adapt to that by providing a composer.json file and add the __xp.php bootstrapper to its files list. Path files (*.pth) are not necessary in this scenario, since Composer's autoload generator will include all the necessary files and provide a vendor/autoload.php which applications typically require. This will always use the locally required XP version, this is the way how composer was intended to work.

Taken from http://reactphp.org/:

// Composer semantics
require 'vendor/autoload.php';

// XP Framework here:
$conn= rdbms\DriverManager::getConnection('sybase://...');

// ReactPHP:
$app = function ($request, $response) use($conn) {
  $response->writeHead(200, ['Content-Type' => 'text/plain']);
  $response->end($conn->select('hello from world where language_id= 47')->next('hello'));
};

$loop = React\EventLoop\Factory::create();
$socket = new React\Socket\Server($loop);
$http = new React\Http\Server($socket, $loop);

$http->on('request', $app);
echo "Server running at http://127.0.0.1:1337\n";

$socket->listen(1337);
$loop->run();

_TODO: Verify our autoloading doesn't conflict with other autoloaders!_

Composer and XP

The optional goal here could be to use composer to combine XP applications. The composer.json file needs to contain a VCS repository as long as we're not registered on packagist:

{
  "repositories": [
    {
      "type": "vcs",
      "url": "https://github.com/thekid/core"
    }
  ],
  "require" : {
    "xp-framework/core" : "dev-rfc/0287"
  }
}

The we can execute install to download the dependency:

$ composer install
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
- Installing xp-framework/core (dev-rfc/0287 ffd70d9)
  Cloning ffd70d9c33d1f20873ddbf2f7451683ff21938b0
Writing lock file
Generating autoload files

This test program works as expected:

<?php
require('vendor/autoload.php');

\util\cmd\Console::writeLine('Hello World');

To make classes work with the XP runners, simply add vendor/autoload.php to a local path file:

$ echo vendor/autoload.php > class.pth

Security considerations

Speed impact

Dependencies

Related documents

https://github.com/thekid/composer
https://github.com/kiesel/xp-composer-installer

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions