Upload
phppro
View
4.055
Download
3
Embed Size (px)
DESCRIPTION
Citation preview
PM* : « code faster »
PHP User Group – Bordeaux, France
2011-04-13
Olivier HOAREAU, PHPPRO
* = « Project Manager » or « PHP Metaframework »PM v0.1.0
What is PM ?
# PM seems to be a basic command line tool …
$ pm <command>
• … a generic command line “shortcuts / aliases” maker / runner
• … a generic packager (.tgz / .zip / .phar / pear) for your app
• … a generic custom code generator using your templates
• … a set of predefined popular commands based on project type detection
• … an external dependencies loader (.tgz / .phar / .zip)
• … a “use it in your language” tool (at least, not only English ;) )
• … an extensible tool based on PHP 5.3+
• … the best friend of Hudson/Jenkins and others for PHP Projects ;)
• … and a lot more (i.e. use it for your custom needs) !
ok, but, it’s also …
OK, but I am already using <whatever>framework, so why switch to PM ?
• PM is not a conventional framework, you don’t need to switch :
– Designed to work with all kind of projects :• No framework projects
• Zend Framework projects
• Symfony projects
• CakePHP, and others !
– Designed to « alias » your framework’s commands for you to keep yourpopular « commands » from one framework to an other (ex: from ZF to SF !) and to « map » your source tree layout
– Designed to work out of the box (almost !) on any PHP project, even PHP projects not using PHP 5.3+ !*
* = you will need to have the PHP 5.3+ cli available on your system at least
Interested ? Start using PM !
# go to your existing project directory or create one$ cd my-existing-project
# download pm.phar file at (or github.com/phppro/pm and’ download’)
https://github.com/downloads/phppro/pm/pm.phar
# enable pm support on your project$ php pm.phar enable
# execute pm for the first time on your project !$ pm
# begin customizing with your needs !$ vi project.php
Not using PHP 5.3+ on your app ?
# install PHP 5.3+ as an extra version (recompile on linux)
# enable pm support on your project
$ <path/to/php/5.3>php pm.phar enable
# edit ‘pm’ or ‘pm.bat’ shell script to replace full path for php
# use pm !
$ pm
Linux users or others, install system-wide
# put ‘pm’ (or pm.bat on windows) in some central directory
$ sudo mkdir /opt/pm
$ sudo cp pm /opt/pm/
$ sudo chmod +x /opt/pm/pm
# optional: put pm.phar in some central directory
$ sudo cp pm.phar /opt/pm/
# then replace pm.phar in ‘pm’ or ‘pm.bat’ by ‘/opt/pm/pm.phar’
# update your $PATH system variable to add /opt/pm directory
# use pm !
$ pm
to avoid ./pm instead of pm
List available commands
# list your bookmarked commands
$ pm
# list all available commands
$ pm -h
# get help on how to use command « tpl »
$ pm -h tpl
# list all available commands that are prefixed with « t »
$ pm -h t
Execute an existing command / alias
# Syntax: pm [common-options] <action> [action-options]
$ pm pkg
$ pm -d display_errors=On audit:cpd
$ pm tu MyClass
$ pm tpl mytemplate --my.variable=theValue
$ pm -o new
Use interactive mode (aka « pm shell »)
# open PM in interactive mode
$ pm -i
PM> -h
PM> tu
…
# quit PM in interactive mode
PM> quit
Add a custom command alias
# edit your configuration file$ vi project.php
---<?php
return array(‘aliases.list’ => array(
‘co’ => ‘!svn commit’,),
);
# use your new alias now !$ pm co
Create a new custom command
# create an new command called ‘my:personal-action’ with some example of primitive you can use inside
$ pm new my:personal-action --example
#read the example provided in the generated class and customize your logic
$ vi _pm/actions/My/PersonalAction.php
---
<?php
…
class PersonalAction extends \PM\Action {
public function run() {
if (false === $this->confirm(‘Are your sure’) ) return;
$feature = new MyClass($this->cfg (‘some.config.key’));
$feature->doSomething($this->arg());
}
}
# use your new command now !
$ pm my:personal-action
$ pm -o my:personal-action
Create a new inline (closure) command
# add directly your inline command to your project.php
$ vi project.php
---
<?php
return array(
‘aliases.list’ => array(
‘replace’ => function ($args) {
echo str_replace($args[0], $args[1], $args[2]);
},
),
);
# use your new command now !
$ pm replace ab cd abcdef
Bookmark popular project commands
# add your popular project commands to the list
$ vi project.php---<?php
return array(‘bookmarks.list’ => array(
‘unit tests’ => ‘pm tu’,‘commit’ => ‘pm co’,‘the very important command to keep in mind’ => ‘do-something’,…
),);
# at anytime, list your bookmarked commands easily !$ pm
Create a new code template
# create an new empty template called ‘my-tpl’ using example
$ pm tpl:new my-tpl --example
# … read generated example in _pm/templates/my-tpl
# … customize your template content
$ mkdir _pm/templates/my-tpl/sources
$ vi _pm/templates/my-tpl/sources/%{[email protected]}.php
---
<?php
class %{[email protected]} { … }
# use your new template now ! (--class.name=… is optional)
$ pm tpl my-tpl --class.name=MyClass
Executing unit tests(using installed PHPUnit tool)
# customizing the location of your unit tests (PHPUnit)
$ vi project.php
---
<?php
return array(
…
‘paths.list’ => array(
‘tests/unit/php’ => ‘test/library’,
…
),
);
# execute unit tests in test/library/MyClassTest.php now !
$ pm tu
$ pm tu MyClass
Customizing an existing command
# replace existing command by yours
$ vi project.php
---
<?php
return array(
‘aliases.list’ => array(
‘tu’ => ‘atoum %{0|.}’,
…
),
);
# execute your customized command now ! (« atoum MyClass »)
$ pm tu MyClass
Enabling logging/trace for a command
# execute your command with debug log enabled
$ pm -o tu
# execute your command with hard-core log enabled
$ pm -e tu
# execute your command by tracing all io.* as info
$ pm -t io=info tu
# execute your command by logging all notice (and above)
$ pm --verbose=notice tu
Use PM in your language (if exists ;))
# execute your command in french (if translated…)$ pm -l=fr-fr tu
# force using french for all team member of the project$ vi project.php---<?phpreturn array(
…‘lang’ => ‘fr-fr’,…
);
$ pm tu
Upgrade your database using scripts
# create repository for your differentials scripts$ pm db:repo:create configs/mysql
# creates differentials scripts for your database$ vi configs/mysql/2/01_all_schema_create_products_table.sql----- dump the content of your differential script here
# set your database credentials and location in your configuration$ vi project.php---<?phpreturn array(
‘databases.list’ => ……
);
# upgrade your database using differential scripts$ pm db:up
Soon available …
Audit your code
# first, index your source code
$ pm source:index
# then, request the index …
# … to list biggest method (in lines) using predefined queries …
$ pm source:query methods.biggest
# … or using pure sql
$ pm source:query "SELECT name FROM methods ORDER BY DESC lines LIMIT 0,10"
# … to get the size per file extension
$ pm source:query "SELECT size FROM files GROUP BY extension"
# … same but exported in CSV
$ pm source:query "SELECT size FROM files GROUP BY extension" --format=csv
Soon available …
Adds conditional features
# example: add ‘co’ alias to commit only if svn client available$ vi project.php---…
‘conditional.sets.list’ => array(…'svn' => 'assertTreeContains:.svn',…
),‘svn.sets.list’ => array(
‘aliases.list’ => array(‘co’ => ‘!svn commit’,
),),
…# if your project is « subversionned » (i.e. you have a .svn directory), use :$ pm co
assertTreeContainsassertTreeNotContainsassertSystemPathContainsOneassertContextFlagExistsassertContextContains…
Adds environment specific features
# example: add ‘cache:clean’ alias only on your integration server$ vi project.php---…
‘environments.list’ => array(…‘integ-01‘ => array(
‘aliases.list’ => array(‘cache:clean’ => ‘!rm –rf /tmp/myapp/cache’,
),),…
),# on your integration server ‘integ-01’, you can now use your command:$ pm --env=integ-01 cache:clean
# to autodetect the environment, use the ‘COMPUTERNAME’ environment variable$ export COMPUTERNAME=integ-01$ pm cache:clean
Adds user specific features
# example: replaces an existing ‘co’ alias by yours only for the user ‘ohoareau‘:$ vi project.php---
‘users.list’ => array(‘ohoareau‘ => array(
‘aliases.list’ => array(‘co’ => ‘!my-specific-co-command’,
),‘user.name’ => ‘Olivier Hoareau’,‘user.email’ => ‘[email protected]’,‘company.name’ => ‘PHPPRO’,‘company.website’ => ‘http://www.phppro.fr’,‘lang’ => ‘fr-fr’,
),),
# you can now use your command:$ pm --user=ohoareau co
# to autodetect the current user, use the ‘USERNAME’ environment variable$ export USERNAME=ohoareau$ pm co
Translates (pm) messagesin your language
# generates a stub for your translation file
$ pm :i18n:new de-de --from=fr-fr
# edit your locale file and translate messages
$ vi _pm/i18n/de-de.php
# send us your locale file _pm/i18n/de-de.php !
Some usage examples takenfrom the real life
As a developer, I want to maintain « textual » specification of my application and distribute
it in PDF
# example: using latex (or markdown, or some other transformable text format) :
$ vi project.php
---
‘aliases.list’ => array(
‘spec:gen‘ => ‘!pdflatex %{/docs/latex}/%{0}.tex --output-directory=%{/docs/generated}’,
),
),
# then, edit your latex files…
# then « generate » pdf from your latex file
$ pm spec:gen feature-xyz
# then send it by mail !
$ pm email:file docs/generated/feature-xyz.pdf [email protected]
As a developer, I want to svn update, executeunit tests before committing in one single
command
# add your custom « sequence » command to your project
$ vi project.php
---
‘aliases.list’ => array(
‘c‘ => array(‘up’, ‘tu’, ‘co’),
),
# then use your alias to code faster !
$ pm c
As an open source project lead developer, I want to package my development into a PEAR-
compatible package in one single command
# specify the list of directories to include
$ vi project.php
---
‘includepaths.list’ => array(
‘library’,
),
# then package !
$ pm pkg --format=pear --version=1.12.3-RC3
# then install / distribute your PEAR compatible package
$ pear install builds/zend-framework-1.12.3-RC3.tgz
Beta
Other real life examples …
• Generate empty controller / model using default commentsand current user info
• Generate model classes using an existing database (tables) using custom tree template
• Update local database directly after a svn update (post-update script)
• List all available useful commands on the project for new incoming developers
• Use same commands on local desktop and on integrationserver (maintenance purpose)
• …
Roadmap
Todo
• Full support for popular frameworks (ZF, Symfony, CakePHP…)• Standalone pm.exe containing PHP 5.3 (+dlls) !• Hard core unit test coverage (code is designed for that)• Debian package + repository for PM• PEAR package for PM (80% done)• Plugin support + Plugin development kit• Ability to share your alias / command with others• Windows installer optionally installing PHP 5.3• PM documentation online• PM web hub• XML / Ini configuration file format (project.xml / project.ini)• Ability to manage project using other technology than PHP• Non regression tests on PM core features• Provide Jenkins (Hudson) plugin for PM
More ideas ?
Want to enhance / contribute ?
Fork / Contribute PM project
# clone PM repository$ git clone [email protected]:phppro/pm.git pm# clone P (underlying framework) repository$ git clone [email protected]:phppro/p.git p
# modify locally PM source code to contribute / enhance !$ cd pm…
# package your local version$ php bins/pm.php pkg# or package + locally deploy (Package + Deploy)$ php bins/pm.php pd
# if you want to contribute, fork pm project on github.com then request# for pull