Pogo accepts instructions using a #!foo
notation. The following are supported:
- Description: Download a package via composer/packagist
- Signature:
#!require <yaml-key-value>
- Example:
#!require symfony/yaml: ~3.0
- Example:
#!require {symfony/yaml: ~3.0, symfony/finder: ~3.0}
- Comment: The
<package>
and<version>
notations match composer'srequire
.
- Description: Specify the location for automatically downloaded packages
- Signature:
#!depdir <yaml-string>
- Example: `#!depdir '/tmp'
- Example: `#!depdir '../var/cache'
- Comment: If the path is relative, it is interpreted as relative to the script file. (This differs from the CLI option
--dl
which defaults to the PWD.) The path may use the following variables:- Environment:
{POGO_BASE}
: This is either env-var POGO_BASE or fallback (such as$HOME/.cache/pogo
or/tmp/pogo
){PHP_X}
: PHP version (MAJOR part){PHP_XY}
:PHP version (MAJOR.MINOR parts){PHP_XYZ}
:PHP version (MAJOR.MINOR.PATCH parts){ENV[...]}
: Reference any environment variable
- Script location
{SCRIPT_DIR}
: The folder containing the main script{SCRIPT_FILE}
: The filename of the main script{SCRIPT_NAME}
: The filename of the main script, but with file-extensions removed_SCRIPTDIR_
(deprecated): The folder containing the main script
- Script content
{CODE_DIGEST}
: A checksum based on the raw code of the script{REQUIRE_DIGEST}
: A checksum based on the#!require
directives of the script{SCRIPT_DIGEST}
: A checksum based on the content and location of the script
- Environment:
- Description: Set the value of
php.ini
option before launching the script. - Signature:
#!ini <yaml-key-value>
- Example:
#!ini variables_order: EGPS
- Example:
#!ini {max_upload_size: 1m, memory_limit: 1g}
- Description: The time-to-live determines the maximum time to retain previously downloaded dependencies.
- The
<qty> <unit>
notation is a strict subset of PHPstrtotime()
. - The
<unit>
can besec
,min
,hour
,day
,week
,month
,year
.
- The
- Signature:
#!ttl <qty> <unit>
- Example:
#!ttl 7 days
- Comment: Any change in dependencies will trigger a new download -- regardless of
ttl
. So what isttl
for? It allows scripts to remain reasonably secure (up-to-date) by default. If you don't want this, you can always peg versions more precisely (~3.0
vs3.4.20
) or a set a long attl
(10 years
).
- Description: After
pogo
updates the dependencies, it needs to callphp
and execute your script. Unfortunately, I have not found a great, one-size-fits-all technique for this delegation. The defaults should execute correctly in most scripting scenarios - but support for nice backtraces might be compromised if you use a#!/usr/bin/env pogo...
header. In that case, you might want to try a different mode. - Signature:
#!run <yaml-string|yaml-key-value>
- Example:
#!run local
- Example:
#!run {with: prepend, extraStuff: true}
- Options:
- Abstract runners: Use these to indicate loosely what you want without committing to a specific implementation
auto
: Letpogo
pick a mechanism.isolate
: Letpogo
pick a mechanism, as long as the mechanism is guaranteed to launch in an isolated sub-process. (Current implementation: useprepend
)local
: Letpogo
pick a mechanism, as long as the mechanism is guaranteed to launch in the same PHP process as pogo. (Current implementation: check for#!
line, then pick eitherrequire
oreval
)
- Concrete runners:
prepend
(isolate): Loosely, this runsphp -d auto_prepend_file=$autoloader $your_script
.require
(local): Loosely, this runsrequire "$your_script";
. This provides better backtraces and debugging because it references the original PHP file on disk; however, if the file has a#!
on the first line, it'll erroneously display it.eval
(local): Loosely, this runseval(cleanup($your_script));
. This may not work as nicely for debugging, but it won't display the extraneous#!
.
- Abstract runners: Use these to indicate loosely what you want without committing to a specific implementation
Most pragmas accept either strings or key-value pairs, e.g.
#!foo somestring
#!bar {key1: value1, key2: value2}
To simplify implementation, pogo
uses a YAML library to parse these. YAML is the most forgiving
of the widely-known formats, so it's reasonably easy to read+write.
In this context, we don't use the full YAML. There are no new-lines, multi-line content, indentation, anchors, or aliases.
Consequently, you should regard these inputs as a subset of YAML -- or, perhaps more precisely, consider the inputs as JSON without the mandatory double-quotes. If the parsing library ever needs to be changed, it will be checked against this subset - but may not be required to have full YAML compliance.