• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Phing for power users - frOSCon8
 

Phing for power users - frOSCon8

on

  • 635 views

 

Statistics

Views

Total Views
635
Views on SlideShare
541
Embed Views
94

Actions

Likes
2
Downloads
6
Comments
0

4 Embeds 94

http://blog.loc 51
http://blog.staging.bitexpert.net 40
http://dex.io 2
http://blog.bitexpert.de 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Phing for power users - frOSCon8 Phing for power users - frOSCon8 Presentation Transcript

    • Phing for power users Stephan Hochdörfer, bitExpert AG
    • Phing for power users About me  Stephan Hochdörfer  Head of IT at bitExpert AG, Germany  enjoying PHP since 1999  S.Hochdoerfer@bitExpert.de  @shochdoerfer
    • Phing for power users I used to be an Ant fanboy...
    • What is Phing? Phing for power users
    • What is Phing? Phing for power users It is a PHP project build system or build tool based on Apache Ant.
    • What is Phing? Phing for power users Domain Specific Language for an project build system.
    • Phing for power users A build system for PHP code? Srsly?
    • Glue for all 3rd party tools Phing for power users
    • How to install Phing? Phing for power users
    • $> pear channel­discover pear.phing.info $> pear install phing/phing How to install Phing? The PEAR way... Phing for power users Installing Phing
    • $> phing ­v Phing 2.5.0 $> pear channel­discover pear.phing.info $> pear install phing/phing How to install Phing? The PEAR way... Phing for power users Installing Phing Running Phing:
    • How to install Phing? Phing for power users Installing Phing globally? WTF?!?
    • How to install Phing? Phing for power users Phing is „just another“ dependency for your project.
    • How to install Phing? The Composer way... Phing for power users
    • { "require": { "phing/phing": "2.5.0" } } How to install Phing? The Composer way... Phing for power users composer.json:
    • { "require": { "phing/phing": "2.5.0" } } $> php composer.phar install Loading composer repositories with package information Installing dependencies   ­ Installing phing/phing (2.5.0)     Downloading: 100%          Writing lock file Generating autoload files How to install Phing? The Composer way... Phing for power users composer.json: Running Composer:
    • How to install Phing? The Composer way... Phing for power users /tmp/myproject    |­vendor    |­­­bin    |­­­­­@phing    |­­­composer    |­­­phing    |­­­­­phing    |­­­­­­­bin    |­­­­­­­­­phing    |­­­­­­­build    |­­­­­­­classes    |­­­­­­­docs    |­­­­­­­etc    |­­­­­­­test
    • How to install Phing? The Composer way... Phing for power users /tmp/myproject    |­vendor    |­­­bin    |­­­­­@phing    |­­­composer    |­­­phing    |­­­­­phing    |­­­­­­­bin    |­­­­­­­­­phing    |­­­­­­­build    |­­­­­­­classes    |­­­­­­­docs    |­­­­­­­etc    |­­­­­­­test $> ./vendor/bin/phing ­v Phing 2.5.0 Running Phing:
    • Phing Basics Phing for power users
    • Phing Basics Phing for power users Project, Target, Task, Properties
    • Phing Basics: Project Phing for power users Root node of a build file containing one or more targets.
    • Phing Basics: Target Phing for power users A group of tasks that run as an entity.
    • Phing Basics: Task Phing for power users Custom piece of code to perform a specific function.
    • Phing Basics: Properties Phing for power users Properties (variables) help to customize execution.
    • Phing Basics: Built-In Properties Phing for power users e.g. host.os, line.separator, phing.version, php.version, …
    • <?xml version="1.0"?> <project name="myproject" default="init"> <target name="init"> <!­­ insert logic here ­­> </target> </project> Phing Basics: Sample Build File Phing for power users
    • <?xml version="1.0"?> <project name="myproject" default="hello"> <target name="hello"  description="Says Hello, world!">  <echo msg="Hello, world!" /> </target> </project> Build File – Hello World example Phing for power users
    • Why Phing? Phing for power users Runs everywhere where PHP runs.
    • Why Phing? Phing for power users No additional depencendies needed (e.g. Java, …).
    • Why Phing? Phing for power users More than 120 predefined tasks to choose from.
    • Why Phing? Phing for power users Easy to extend by writing custom tasks in PHP.
    • Enforce Internal Targets Phing for power users
    • Enforce Internal Targets Phing for power users <?xml version="1.0"?> <project name="myproject" default="hello"> <target name="init" description="Property initialization"> <property name="Hello" value="Hello, world!" /> </target> <target name="hello" depends="init"> <echo msg="${Hello}" /> </target> </project>
    • Enforce Internal Targets Phing for power users $> ./vendor/bin/phing -f build.xml hello /tmp/myproject/build.xml myproject > init: myproject > hello: [echo] Hello, world! BUILD FINISHED Total time: 0.0474 seconds
    • Enforce Internal Targets Phing for power users $> ./vendor/bin/phing -f build.xml init /tmp/myproject/build.xml myproject > init: BUILD FINISHED Total time: 0.0476 seconds
    • Enforce Internal Targets Phing for power users $> ./vendor/bin/phing -l Buildfile: /tmp/myproject/build.xml Default target: --------------------------------------------------------- hello Main targets: --------------------------------------------------------- init Property initialization Subtargets: --------------------------------------------------------- hello
    • Enforce Internal Targets Phing for power users Internal targets are just helpers like private methods.
    • <?xml version="1.0"?> <project name="myproject" default="hello"> <target name="-init" description="Property initialization"> <property name="Hello" value="Hello, world!" /> </target> <target name="hello" depends="-init"> <echo msg="${Hello}" /> </target> </project> Enforce Internal Targets – The solution Phing for power users
    • Enforce Internal Targets – The solution Phing for power users $> ./vendor/bin/phing -f build.xml -init Unknown argument: -init phing [options] [target [target2 [target3] ...]] Options: -h -help print this message -l -list list available targets -v -version print the version information -q -quiet be extra quiet -verbose be extra verbose -debug print debugging information Report bugs to <dev@phing.tigris.org>
    • Enforce Internal Targets – The solution Phing for power users Are the targets really hidden?
    • Enforce Internal Targets Phing for power users $> ./vendor/bin/phing -l Buildfile: /tmp/myproject/build.xml Default target: --------------------------------------------------------- hello Main targets: --------------------------------------------------------- -init Property initialization Subtargets: --------------------------------------------------------- hello
    • Enforce Internal Targets Phing for power users $> ./vendor/bin/phing -l Buildfile: /tmp/myproject/build.xml Default target: --------------------------------------------------------- hello Main targets: --------------------------------------------------------- -init Property initialization Subtargets: --------------------------------------------------------- hello
    • Enforce Internal Targets (Improved Version) Phing for power users <?xml version="1.0"?> <project name="myproject" default="hello"> <target name="-init" hidden="true" description="Property initialization"> <property name="Hello" value="Hello, world!" /> </target> <target name="hello" depends="-init"> <echo msg="${Hello}" /> </target> </project>
    • $> ./vendor/bin/phing -l Buildfile: /tmp/myproject/build.xml Default target: --------------------------------------------------------- hello Subtargets: --------------------------------------------------------- hello Enforce Internal Targets (Improved Version) Phing for power users
    • Custom Tasks Phing for power users
    • Custom Tasks Phing for power users Phing can do way more than simple exec calls!
    • Custom Task (Adhoc definition) Phing for power users <?xml version="1.0"?> <project name="myproject" default="hello"> <target name="init"> <adhoc-task name="mytask"><![CDATA[ class MyTask extends Task { /** * (non-PHPdoc) * @see Task::main() */ public function main() { // Custom code here... } } ]]></adhoc-task> </target> <target name="hello" depends="init"> <mytask /> </target> </project>
    • <?php require_once 'phing/Task.php'; class MyTask extends Task { /** * (non-PHPdoc) * @see Task::main() */ public function main() { // Custom code here... } } Custom Task (External file) Phing for power users
    • <?xml version="1.0"?> <project name="myproject" default="hello"> <target name="init"> <taskdef name="mytask" classpath="${project.basedir}" classname="MyApp.Common.Phing.MyTask" /> </target> <target name="hello" depends="init"> <mytask /> </target> </project> Custom Task (External file) Phing for power users
    • <?php require_once 'phing/Task.php'; class MyTask extends Task { protected $file; /** * @param string $file */ public function setFile($file) { $this->file = $file; } /** * @see Task::main() */ public function main() { // Custom code here... } } Custom Task with Parameters Phing for power users
    • <?xml version="1.0"?> <project name="myproject" default="hello"> <target name="init"> <taskdef name="mytask" classpath="${project.basedir}" classname="MyApp.Common.Phing.MyTask" /> </target> <target name="hello" depends="init"> <mytask file="myfile.txt" /> </target> </project> Custom Task with Parameters Phing for power users
    • Properties File Phing for power users
    • Properties File Phing for power users Use properties to cutomize build behaviour.
    • <?xml version="1.0"?> <project name="myproject" default="hello"> <target name="hello"  description="Says whatever you want to say"> <property file="./build.properties" />  <echo msg="${Hello}" /> </target> </project> Properties File Phing for power users
    • <?xml version="1.0"?> <project name="myproject" default="hello"> <target name="hello"  description="Says whatever you want to say"> <property file="./build.properties" />  <echo msg="${Hello}" /> </target> </project> Properties File Phing for power users Hello=Hello, world! build.properties:
    • Properties File Phing for power users $> phing Buildfile: /tmp/myproject/build.xml myproject > hello: [property] Loading /tmp/myproject/build.properties [echo] Hello, world! BUILD FINISHED Total time: 0.0601 seconds
    • Properties File - Improved version Phing for power users
    • Properties File - Improved version Phing for power users Requirement: Externalize properties but offer customization capabilities!
    • <?xml version="1.0"?> <project name="myproject" default="hello"> <target name="hello" depends="init"> <echo msg="${Hello}" /> </target> <target name="init" depends="prop, local-prop"> <!-- some more init logic --> </target> <target name="prop"> <echo message="Loading default build.properties"/> <property file="build.properties" /> </target> Properties File - Improved version Phing for power users
    • <target name="local-prop" if="local-prop.exists" depends="local-prop-check"> <echo message="Loading custom properties!"/> <property file="local.properties" override="true"/> </target> <target name="local-prop-check"> <available file="local.properties" property="local-prop.exists" /> </target> </project> Properties File - Improved version Phing for power users
    • $> phing Buildfile: /tmp/myproject/build.xml myproject > prop: [echo] Loading default build.properties [property] Loading /tmp/myproject/build.properties myproject > local-prop-check: myproject > local-prop: myproject > init: myproject > hello: [echo] Hello, world! BUILD FINISHED Total time: 0.1383 seconds Properties File - Improved version Phing for power users
    • $> phing Buildfile: /tmp/myproject/build.xml myproject > prop: [echo] Loading default build.properties [property] Loading /tmp/myproject/build.properties myproject > local-prop-check: myproject > local-prop: [echo] Loading custom properties! [property] Loading /tmp/myproject/local.properties myproject > init: myproject > hello: [echo] Hello my world! BUILD FINISHED Total time: 0.0493 seconds Properties File - Improved version Phing for power users
    • build.properties example Phing for power users phpunit.path=vendor/bin/phpunit phpunit.junit.log=build/logs/junit.xml phpunit.coverage.clover=build/logs/clover.xml phpunit.coverage.html=build/coverage phpcs.path=vendor/bin/phpcs phpcs.log=build/logs/checkstyle.xml sencha.senchaCmd=/user/local/lib/sencha/sencha sencha.jsb3File=app.jsb3
    • build.properties example Phing for power users Use distinct naming conventions for your properties.
    • Accessing application configuration Phing for power users
    • Accessing application configuration Phing for power users Duplicating configuration code is a bad habit.
    • Accessing application configuration Phing for power users <?php require_once 'phing/Task.php'; class ConfigMapperTask extends Task { /** * @see Task::main() */ public function main() { // will import $APP_CONF in local context require_once('src/bootstrap.php'); $project = $this->project; $project->setProperty( 'db.host', $APP_CONF['db_host']); $project->setProperty( 'db.database', $APP_CONF['db_database']); $project->setProperty( 'db.user', $APP_CONF['db_user']); $project->setProperty( 'db.password', $APP_CONF['db_passwd']); } }
    • Accessing application configuration Phing for power users <?xml version="1.0"?> <project name="myproject" default="hello"> <taskdef name="readAppConfig" classpath="${phing.dir}/src/" classname="MyApp.Common.Phing.AppConfigTask" /> <target name="init" depends="prop, local-prop"> <readAppConfig /> </target> <target name="prop"> <echo message="Load default build.properties"/> <property file="build.properties" /> </target> <target name="local-prop" if="local-prop.exists" depends="local-prop-check"> <!-- […] --> </project>
    • Imports for Targets can help structuring Phing for power users
    • <?xml version="1.0"?> <project name="myproject" default="app:run"> <!-- The following target namespaces exist: db:* - Database specific targets app:* - Application specific tasks ci:* - CI server specific tasks --> <import file="build/build.db.xml" /> <import file="build/build.app.xml" /> <import file="build/build.ci.xml" /> </project> Imports for Targets can help structuring Phing for power users
    • <?xml version="1.0"?> <project name="myproject" default="app:run"> <!-- The following target namespaces exist: lib1:* - Targets imported from lib1 lib2:* - Targets imported from lib2 app:* - Local application targets --> <import file="vendor/vendor1/lib1/build/build.xml" /> <import file="vendor/vendor2/lib2/build/build.xml" /> <import file="build/build.app.xml" /> </project> Import Targets: Composer packages Phing for power users
    • Import Targets: Path handling Phing for power users Be aware that imports behave like include in PHP!
    • <?xml version="1.0"?> <project name="myproject" default="lib1:run"> <!-- The following target namespaces exist: lib1:* - Targets imported from lib1 --> <import file="vendor/lib1/build/build.xml" /> </project> Import Targets: Path handling Phing for power users build.xml
    • <?xml version="1.0"?> <project name="lib1" default="lib1:run"> <target name="lib1:run"> <echo msg="Local dir: ${phing.dir.lib1}" /> <echo msg="Global dir: ${phing.dir}" /> </target> </project> <?xml version="1.0"?> <project name="myproject" default="lib1:run"> <!-- The following target namespaces exist: lib1:* - Targets imported from lib1 --> <import file="vendor/lib1/build/build.xml" /> </project> Import Targets: Path handling Phing for power users build.xml vendor/lib1/build/build.xml
    • $> ./vendor/bin/phing Buildfile: /tmp/myproject/build.xml myproject > lib1:run: [echo] Local dir: /tmp/myproject/vendor/lib1/build [echo] Global dir: /tmp/myproject BUILD FINISHED Total time: 0.0411 seconds Import Targets: Path handling Phing for power users
    • Import Targets: Path handling Phing for power users Be aware to always(!) use the projects name in lowercase format!
    • Import Targets: Path handling Phing for power users It`s ${phing.dir.myproject} not ${phing.dir.MyProject}!
    • Distinct Target Naming Phing for power users
    • <?xml version="1.0"?> <project name="myproject" default="ci:run-tests"> <target name="app:clean-cache"> </target> <target name="app:create-cache"> </target> <target name="db:migrate"> </target> <target name="js:minifiy"> </target> <target name="ci:lint"> </target> <target name="ci:run-tests"> </target> </project> Distinct Target Naming Phing for power users
    • <?xml version="1.0"?> <project name="myproject" default="app:create-cache"> <target name="app:clean-cache" description="Removes all cache files."> </target> <target name="app:create-cache" description="Builds the cache files from the xml configuration."> </target> </project> Adding meaningful descriptions Phing for power users
    • $> phing -l Buildfile: /tmp/myproject/build.xml Default target: ----------------------------------------------------- app:create-cache Builds the cache files from the xml configuration. Main targets: ------------------------------------------------------ app:clean-cache Removes all cache files. app:create-cache Builds the cache files from the xml configuration. Adding meaningful descriptions Phing for power users
    • Prompt user for input Phing for power users <?xml version="1.0"?> <project name="myproject" default="run"> <target name="run"> <!-- tag the database --> <input propertyname="tag" defaultValue="mytag">Tag to create?</input> <liquibase-tag tag="${tag}" jar="/opt/liquibase/liquibase.jar" classpathref="/opt/liquibase/lib/mysql.jar" changelogFile="${project.basedir}/diff.xml" username="liquibase" password="liquibase" url="jdbc:mysql://localhost/myproject"/> </target> </project>
    • Calling PHP functions from Phing Phing for power users
    • Calling PHP functions from Phing Phing for power users <?xml version="1.0"?> <project name="myproject" default="run"> <target name="run"> <!-- Returns canonicalized absolute pathname --> <php function="realpath" returnProperty="app.dir"> <param value="${app.dir}"/> </php> </target> </project>
    • Restrict user access Phing for power users
    • <?xml version="1.0"?> <project name="myproject" default="run"> <target name="run"> <!-- Check for root user --> <if> <not> <equals arg1="${env.USER}" arg2="root" /> </not> <then> <fail message="Wrong user!" /> </then> </if> </target> </project> Restrict user access Phing for power users
    • Path handling Phing for power users
    • Path handling Phing for power users <?xml version="1.0"?> <project name="myproject" default="ci:phpunit"> <!-- ... --> <target name="ci:phpunit" depends="-init, -ci:prepare"> <resolvepath propertyName="phpunit.path.abs" dir="${phing.dir}" file="${phpunit.path}"/> <exec executable="${phpunit.path.abs}" /> </target> </project>
    • Phing + Jenkins Phing for power users
    • Phing + Jenkins Phing for power users Install the Jenkins Phing plugin
    • Phing for power users
    • Phing for power users
    • Phing for power users
    • Phing + Composer + Jenkins Phing for power users
    • Phing + Composer + Jenkins Phing for power users Install the Jenkins EnvInject plugin
    • Phing for power users
    • Phing for power users
    • Phing for power users
    • Phing for power users
    • Follow conventions Phing for power users
    • Follow conventions Phing for power users Phing expects your build file to be called build.xml and the build’s properties file build.properties
    • Follow conventions Phing for power users Pick meaningful, human-readable names for targets and properties.
    • Follow conventions Phing for power users Make build files self-contained.
    • Thank you!
    • http://joind.in/9023
    • Phing for power users Image Credits http://www.sxc.hu/photo/629370 http://www.sxc.hu/photo/615731