pestle
pestle copied to clipboard
Odd behaviour when invoking runner.php directly
From a fresh master checkout.
Invoking runner.php directly produces a stack trace where as using pestle_dev doesn't. I'm not really sure why this is happening.
root@12c061acd73d:~/pestle# php runner.php help
PHP Fatal error: Cannot redeclare Pulsestorm\Pestle\Library\exitWithErrorMessage() (previously declared in /root/pestle/library/a
ll.php:10393) in /root/pestle/modules/pulsestorm/pestle/library/module.php on line 10
PHP Stack trace:
PHP 1. {main}() /root/pestle/runner.php:0
PHP 2. main() /root/pestle/runner.php:7
PHP 3. Pulsestorm\Pestle\Runner\main() /root/pestle/runner.php:5
PHP 4. Pulsestorm\Pestle\Runner\doPestleImports() /root/pestle/modules/pulsestorm/pestle/runner/module.php:372
PHP 5. Pulsestorm\Pestle\Importer\pestle_import() /root/pestle/modules/pulsestorm/pestle/runner/module.php:180
PHP 6. Pulsestorm\Pestle\Importer\extractFunction() /root/pestle/modules/pulsestorm/pestle/importer/module.php:11
PHP 7. Pulsestorm\Pestle\Importer\includeModule() /root/pestle/modules/pulsestorm/pestle/importer/module.php:18
root@12c061acd73d:~/pestle# php ./pestle_dev help
_ _
| | | |
_ __ ___ ___| |_| | ___
| '_ \ / _ \/ __| __| |/ _ \
| |_) | __/\__ \ |_| | __/
| .__/ \___||___/\__|_|\___|
| |
|_|
pestle by Pulse Storm LLC
Usage:
pestle command_name [options] [arguments]
Available commands:
Codecept
codecept:convert-selenium-id-for-codecept Converts a selenium IDE html test for conception
Magento2
magento2:fix-direct-om ALPHA: Fixes direct use of PHP Object Manager
magento2:fix-permissions-modphp ALPHA: "Fixes" permissions for development boxes
magento2:convert-system-xml ALPHA: Partially Converts Magento 1 system.xml into Magento 2 system.xml
magento2:convert-observers-xml ALPHA: Partially converts Magento 1 config.xml to Magento 2
magento2:extract-mage2-system-xml-paths Generates Mage2 config.xml
magento2:convert-class ALPHA: Partially converts Magento 1 class to Magento 2
magento2:path-from-class Turns a PHP class into a Magento 2 path
magento2:read-rest-schema BETA: Magento command, reads the rest schema on a Magento system
magento2:class-from-path Turns a Magento file path into a PHP class
magento2:check-templates Checks for incorrectly named template folder
Magento2 Generate
magento2:generate:menu Generates configuration for Magento Adminhtml menu.xml files
magento2:generate:module Generates new module XML, adds to file system
magento2:generate:psr-log-level For conversion of Zend Log Level into PSR Log Level
magento2:generate:preference Generates a Magento 2.1 ui grid listing and support classes.
magento2:generate:route Creates a Route XML
magento2:generate:crud-model Generates a Magento 2 CRUD/AbstractModel class and support files
magento2:generate:schema-upgrade BETA: Generates a migration-based UpgradeSchema and UpgradeData classes
magento2:generate:theme Generates Theme Configuration
magento2:generate:full-module Creates shell script with all pestle commands needed for full module output
magento2:generate:ui:form Generates a Magento 2 UI Component form configuration and PHP boilerplate
magento2:generate:observer Generates Magento 2 Observer
magento2:generate:controller-edit-acl Edits the const ADMIN_RESOURCE value of an admin controller
magento2:generate:acl Generates a Magento 2 acl.xml file.
magento2:generate:acl:change-title Changes the title of a specific ACL rule in a Magento 2 acl.xml file
magento2:generate:command Generates bin/magento command files
magento2:generate:plugin-xml Generates plugin XML
magento2:generate:install BETA: Generates commands to install Magento via composer
magento2:generate:config-helper Generates a help class for reading Magento's configuration
magento2:generate:di Injects a dependency into a class constructor
magento2:generate:registration Generates registration.php
magento2:generate:view Generates view files (layout handle, phtml, Block, etc.)
magento2:generate:ui:add-column-sections Generates a Magento 2.1 ui grid listing and support classes.
magento2:generate:ui:add-column-actions Generates a Magento 2.1 ui grid listing and support classes.
magento2:generate:ui:grid Generates a Magento 2.1 ui grid listing and support classes.
magento2:generate:ui:add-to-layout Adds a <uiComponent/> node to a named node in a layout update XML file
magento2:generate:remove-named-node Removes a named node from a generic XML configuration file
Magento2 Scan
magento2:scan:registration Scans Magento 2 directories for missing registration.php files
magento2:scan:acl-used Scans modules for ACL rule ids, makes sure they're all used/defined
magento2:scan:class-and-namespace BETA: Scans a Magento 2 module for misnamed PHP classes
magento2:scan:htaccess ALPHA: Checks for missing Magento 2 HTACCESS files from a hard coded list
Magento2 Search
magento2:search:search-controllers Searches controllers
Nexmo
nexmo:store-credentials One Line Description
nexmo:verify-sendcode One Line Description
nexmo:send-text Sends a text message
nexmo:verify-request Sends initial request to verify user's phone number
Parsing
parsing:csv-to-iif BETA: Converts a CSV file to .iif
parsing:citicard BETA: Parses Citicard's CSV files into yaml
Pestle
pestle:build-command-list Builds the command list
pestle:baz-bar Another Hello World we can probably discard
pestle:dev-namespace BETA: Used to move old pestle files to module.php -- still needed?
pestle:foo-bar ALPHA: Another Hello World we can probably discard
pestle:hello-argument A demo of pestle argument and option configuration/parsing
pestle:dev-import Another Hello World we can probably discard
pestle:export-module ALPHA: Seems to be a start at exporting a pestle module as functions.
pestle:generate-command Generates pestle command boiler plate
pestle:clear-cache BETA: Clears the pestle cache
pestle:pestle-run-file ALPHA: Stub for running a single PHP file in a pestle context
Php
php:format-php ALPHA: Experiments with a PHP formatter.
php:extract-session ALPHA: Extracts data from a saved PHP session file
php:test-namespace-integrity ALPHA: Tests the "namespace integrity? Not sure what this is anymore.
Pulsestorm
pulsestorm:md-to-say Converts a markdown files to an aiff
pulsestorm:monty-hall-problem Runs Simulation of "Monty Hall Problem"
pulsestorm:build-book BETA: Command for building No Frills Magento 2 Layout
pulsestorm:orphan-content BETA: Used to scan my old pre-Wordpress archives for missing pages.
pulsestorm:pandoc-md BETA: Uses pandoc to converts a markdown file to pdf, epub, epub3, html, txt
Uncategorized
help Alias for list
list-commands Lists help
selfupdate Updates the pestle.phar file to the latest version
test-output A test command for the output function that should probably be pruned
testbed Test Command
hello-world A Hello World command. Hello World!
version One Line Description
root@12c061acd73d:~/pestle#
This one's more an explanation/context for why this happens -- as much to get it written down somewhere as anything else. As of right now "the right" way to invoke pestle from the command line is via the pestle_dev script.
One of pestle's goals is to implement a python-like import system for PHP -- something that organizes code into individual modules, and allows users to import specific functions into their modules. Implementing this meant some Reflection and building up lists of functions in the /tmp/pestle_cache
folder, and we're actively thinking of different/better ways to handle this. Those tradeoffs were acceptable to use for running this code via pestle.phar
.
However -- if someone wants to use a pestle function in their own project -- the whole /tmp/pestle_cache
folder seems like a burden too far. For this "pestle as PHP/Composer library" context, we generate an all.php
file that contains the entire pestle library as a single include, with functions namespaced. Then, we have this library function included via a second PHP file, via the composer autoload feature
"autoload": {
"files": ["library/autoload.php"]
},
All a user needs to do is include pestle via the composer file, and then can reuse any of our functions. Again, this is a crude, initial approach that we may change over time.
The problem this created: We want all.php
loaded for folks who include this project in theirs, but for pestle.phar, pestle_dev, unit tests, etc., we do not want this all.php
loaded. Instead we want the "only imports single functions" behavior.
That's why library/autoload.php has a number of early return checks that attempt to detect the context of the current request. For example -- this checks if the current context is a PHPUnit run
$backtrace = debug_backtrace();
$top = array_pop($backtrace);
$file = '';
if(isset($top['file']))
{
$file = strToLower($top['file']);
}
$parts = explode('/', $file);
$last = array_pop($parts);
if(strpos($last, 'phpunit') !== false)
{
return;
}
If it is, the file returns. There's other checks as well -- but if none of them reach their respective return
statements, we assume this is just some random PHP project that wants a pestle function, and we pull in all.php
include __DIR__ . '/all.php';
The Problem in this Issue: The runner.php
script invokes pestle in its "real" mode, where pestle_import imports individual functions via the /tmp/pestle_cache
business. However, there's not a check in autoload.php
that checks if you're running runner.php
directly. There are checks to see if you're invoking things via pestle
, pestle.phar
, or pestle_dev
//running as pestle_dev, pestle.phar, or pestle
global $argv;
if(isset($argv[0]))
{
$parts = explode('/', $argv[0]);
$last = strToLower(array_pop($parts));
if(in_array($last, ['pestle', 'pestle_dev', 'pestle.phar']))
{
return;
}
}
When you're see the following error
PHP Fatal error: Cannot redeclare Pulsestorm\Pestle\Library\exitWithErrorMessage() (previously declared in /root/pestle/library/all.php:10393) in
/root/pestle/modules/pulsestorm/pestle/library/module.php on line 10
PHP Stack trace:
That's PHP complaining exitWithErrorMessage
was already defined when the all.php
file was included.
So, that's where things stand. Less a deliberate design and more a series of small steps. The pestle_import
mechanism may be overhauled when we implement things like importing multiple functions are once, or an entire module's worth of functions. At that time we'll probably revisit the whole "running in pestle.phar mode vs. running in "normal composer library mode"" question.
Given all this is due for a major refactoring anyway, I'm not super wild about endlessly adding more special cases into autoload.php
-- although if a pull request came in that was able to special case a direct call to runner from a "pestle as library" context I'd be open to that.
I see...
I think there several ways this problem can be approached
-
How about declaring/defining a special namespace/function within runner.php and then checking for that in library/autoload.php? (with this you can name the invoking command anything you like!)
-
runner.php can check if it was called from pestle_dev and if not exec pestle_dev (hacky/short sighted approach?)
I think this part of the readme could use an update if ['pestle', 'pestle_dev', 'pestle.phar'] become the only three officially supported entry points
But I'm not sure if having the command be dependent of its name ($argv[0]) is a good idea all together like you've already mentioned
If you're interested in working on the framework itself, you can use the runner.php in the project root. I personally use it by dropping the following in my ~/bin.
#File: ~/bin/pestle_dev
#!/usr/bin/env php
<?php
require_once('/Users/alanstorm/Documents/github/astorm/pestle/runner.php');