thekid/rfc — Issue #166: RFC 0166: XP Runners
Author: thekid
Created: 2011-10-09 15:32:05+00:00
State: closed
Labels: implemented, rfc

Scope of Change
====
This RFC defines the standards for the XP runners.

Rationale
====
Clarification is needed.

Functionality
====
XP runners make it easy to run XP classes.

Hello World-Example
----
Hello.class.php:

```php

```

To run this code with php, we would have to type:

```
$ php
> -dinclude_path="/path/to/xp:/path/to/xp/xp-rt-X.X.X.xar:."
> -dauto_prepend_file="lang.base.php"
> -r "uses('Hello'); Hello::main($argv);"
> World

```

If we use the XP runner, we simply type:

```
$ xp Hello World

```

Boot classpath
----
The boot classpath consists of the following entries:

Release:
* /path/to/xp - where lang.base.php resides
* /path/to/xp/lib/xp-rt-X.X.X.xar - runtime XAR
* /path/to/xp/lib/xp-net.xp_framework-X.X.X.xar - tools and tests

Dev:
* /path/to/xp/skeleton - where lang.base.php resides
* /path/to/xp/ports/classes - where net/xp_framework is

These files compose the essentials of the XP framework.

Path files
----
Inspired by a little-known feature in Python (`.pth`-files), the
XP framework loads path files (which contain a list of paths, each on a
line by itself) and adds them to `include_path`.

```
# boot.pth from a released version
../
../lib/xp-rt-5.6.7RC1.xar
../lib/xp-net.xp_framework-5.6.7RC1.xar

```

Paths inside `.pth` files are expanded relative to the file they
are contained in. The special tilde character (`~`) may be used
to reference the home directory (`getenv HOME` on Un*x and Cygwin,
`getenv HOMEPATH` on Windows).

Path files are searched for in the following locations:
* The directory the runners exist in (`dirname $0`/*.pth)
* The current directory (`pwd`/*.pth)

Order in path files is significant - paths will be added to the classpath
in the order they appear inside the file!

Released versions
----
Every release comes bundled with the runners:

```
+ xp-VERSION/
+- lang.base.php
+- lib/
| +- xp-rt-VERSION.xar
| +- xp-net.xp_framework-VERSION.xar
| +- ... (further xar files)
+- bin/
+- boot.pth
+- xp
+- xpcli
+- ... (further utilities)

```

The runners all use `../lang.base.php`, `../lib/xp-rt-VERSION.xar`
and `../lib/xp-net.xp_framework-VERSION.xar` to ensure no global
`include_path` setting will "disturb" the class loading process.
Assume you have installed the XP framework to `/usr/local/lib`.
By adding `/usr/local/lib/xp-VERSION/bin` to your `PATH`, you can
type "xp" in any shell to invoke the xp utility.

To add XAR files to the class path temporarily, you can use the "-cp" option,
e.g. `xp -cp "/path/to/thekid.xar" de.thekid.Hello` or
`xp -cp "/path/to/classes" de.thekid.Hello`. To permanently add paths or
xar files to the classpath, create a file containing these and save it
to /path/to/xp-VERSION/bin/. Its name is irrelevant, though it must end in ".pth".

Development checkout
----
For a development checkout (needed for developing the XP framework itself), the
directory tree looks as follows:

```
+ trunk/
+- skeleton/
| +- lang.base.php
| +- lang/
| | +- Object.class.php
| | +- ... (lang package contents)
| +- ... (packages)
+- ports/
+- classes/
| +- net/
| +- ... (further non-core classes)
+- technologies/
+- env/
+- bin/
+- xp
+- xpcli
+- ... (further utilities)

```

Because the env/bin directory contains the "raw" form of our utilities,
it is required that the platform-specific versions be setup in another
directory, for example as follows:

```
+ xp
+- bin
| +- boot.pth
| +- xp
| +- xpcli
| +- ... (further utilities)
+- trunk/
+- ... (see above)

```

The boot.pth file would contain:

```
../trunk/skeleton
../trunk/ports/classes

```

Another setup (if you don't mind you ~/bin/-directory being "cluttered"
with XP binaries):

```
+ ~
+- bin/
| +- boot.pth
| +- xp
| +- xpcli
+- devel/
+- xp/
+- trunk/
+- ... (see above)

```

The boot.pth file would contain:

```
../devel/xp/trunk/skeleton
../devel/xp/trunk/ports/classes

# or (because it's equivalent in this case)
~/devel/xp/trunk/skeleton
~/devel/xp/trunk/ports/classes

```

Project Development and the classpath
----
If you are developing applications ontop of the XP framework, you probably
have the following directory layout:

```
+ PROJECT
+- lib/
| +- app-specific.xar
| +- ... (further supporting libraries)
+- classes/
| +- de/
| +- thekid/
| +- SomeClass.class.php
| +- ... (further classes and packages)
+- ... (further project-specific directories, e.g. xsl or doc_root)

```

In a slightly different setup, we'd have a "common" libdir:

```
+ xp/
+- common/
| +- lib/
| +- supporting.xar
| +- ... (further supporting libraries)
+- projects/
+- PROJECT
+- lib/
| +- app-specific.xar
| +- ... (further app-specific libraries)
+- ... (further project-specific directories)

```

To add the "classes" directory and the xars in "lib" (and "common/lib") to
your classpath, add a path-file to the PROJECT directory (from which the
work will be done):

```
# development.pth
classes/
lib/app-specific.xar

# For the common/lib-case, add
../../common/lib/supporting.xar

```

Released projects and the classpath
----
The above project is released in a XAR file, and all libraries it depends
on are bundled:

```
+ PROJECT-VERSION
+- lib/
| +- PROJECT-VERSION.xar
| +- supporting.xar
| +- app-specific.xar
| +- ... (further supporting libraries)
+- ... (further project-specific directories, e.g. xsl or doc_root)

```

To add the "PROJECT-VERSION.xar" and all other xars in the "lib" directory
to your classpath:

```
# release.pth
lib/PROJECT-VERSION.xar
lib/app-specific.xar
lib/supporting.xar

```

Framework*2
----
Developing an internal framework ontop of the released XP framework
you'd have a directory layout as follows:

```
+ xp/
+- classes/
+- com/
+- oneandone/
+- session/
| +- Session.class.php
| +- SessionProtocol.class.php
| +- ... (further classes and packages)
+- SomeClass.class.php
+- ... (further classes and packages)

```

From this directory, the XARs in the common/lib directory would be created.
While developing, it is easier to have the xp/classes directory in your
classpath; to add it, add the directory to your XP installation.

Assuming the xp-directory from above is in `/home/thekid/devel/xp` and
the public XP framework installed in `/usr/local/lib/xp-VERSION` and
you are fine with allowing this for all users:

```
# /usr/local/lib/xp-VERSION/bin/com.1and1.pth
~/devel/xp/classes/

```

Websites
----
When running inside a webserver via PHP's Apache Module, the runners aren't
invoked. The boot classpath must be set from within the web server
configuration. Here's an example for apache (on Windows):

```

RewriteEngine on
RewriteRule !^/static /index.php

DirectoryIndex index.php
DocumentRoot c:/cygwin/home/thekid/dialog/doc_root/

# Boot classpath
php_value include_path ".;d:/share/xp-5.7.0;d:/share/xp-5.7.0/lib/xp-rt-5.7.0.xar"

```

The index.php file is a generic file:

```php

```

It determines the class path from `[DOCUMENT_ROOT]/../WEB-INF/web.ini`.

```
; Dialog web configuration

[application]
class-path="../lib/dialog-2.4.0.xar"

[/xml]
package="de.thekid.dialog.scriptlet"

```

Core utility: xp
----
Basic runner

```
# Display version
$ xp [opt] -v

# Evaluate
$ xp [opt] -e 'echo create(new Object())->hashCode();'

# Run main class from xar file (via META-INF/manifest.ini)
$ xp [opt] -xar [app.xar]

# Run class
$ xp [opt] class.with.static.main.Method

opt is one of:
* -cp [path-list] - Set classpath

```

Core utility: xpcli
----
The xp command class runner. An alias for `xp util.cmd.Runner`.

```
# Runs class by fully qualified name
$ xpcli class.which.extends.util.cmd.Command

# Runs class by filename
$ xpcli class/which/extends/util/cmd/Command.class.php

```

Core utility: xar
----
Works with XAR archives. An alias for `xp net.xp_framework.xar.Xar`.

```
$ xar [instruction] target.xar [file-or-directory*]

instruction is one of:
* c[v]f - Create
* x[v]f - Extract
* t[v]f - List
* s[v]f - Show

file-or-directory is one of:
* a directory - all files and directories in the directory will be added
* a file - the file will be added

```

Development utility: n
----
Starts editor.

```
$ n [class-or-file*]

class-or-file is one of:
* fully.qualified.class.Name
* fully/qualified/class/Name.class.php

```

Development utility: unittest
----
Runs classes that extend the unittest.TestCase class. An alias for
`xp net.xp_framework.unittest.runner.cli.CliRunner`.

```
$ unittest [class-or-config*]

class-or-config is one of:
* class.which.extends.unittest.TestCase - a fully qualified class name
* class/which/extends/unittest/TestCase.class.php - a filename
* unittests/config.ini - a property file

```

Development utility: doclet
----
Runs doclets.

```
$ doclet class.which.extends.text.doclet.Doclet

```

Development utility: qnt
----
Runs Quantum buildfiles (`build.cxml`).

```
$ qnt [target]

```

Development utility: cgen
----
Code generator utility.

```
# Generate parsers
$ cgen [options] Parser

# Generate remote stubs via ESDL
$ cgen [options] Stubs [dsn]

# Generate datasets
$ cgen [options] DataSets [dsn]

options is one of:
* -o dir/: Generate class files to directory dir/ (default: ./)

```

Development utility: xcc
----
Compiles XP sourcecode to bytecode.

```
$ xcc any/source/File.xp

```

Development utility: opcodes
----
Dumps opcode instructions from compiled bytecode.

```
$ opcodes any/compiled/File.xpc

```

Security considerations
====
None.

Speed impact
====
None.

Dependencies
====
None.

Related documents
====
* [http://mindprod.com/jgloss/classpath.html classpath Java Glossary]
* [http://bob.pythonmac.org/archives/2005/02/06/using-pth-files-for-python-development/ Using .pth files for Python development]

Comments
====
friebe, Mon May 12 17:14:05 2008
----
I would like to move net.xp_framework.unittest.runner.cli.CliRunner
and net.xp_framework.xar.Xar to skeleton/ somewhere to get rid of
the dependency on xp-net.xp_framework-X.X.X.xar

friebe, Mon May 12 17:47:12 2008
----
The utilities opcodes and xcc only apply to the compiled version of
XP, see xp-framework/rfc #52.

friebe, Mon May 12 17:52:04 2008
----
The utilities cgen and doclet are new!

friebe, Mon May 12 17:53:43 2008
----
The utility "qnt" is currently under development in the XP framework's
experiments.