Phing for power users - frOSCon8

  • 506 views
Uploaded on

 

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
506
On Slideshare
0
From Embeds
0
Number of Embeds
4

Actions

Shares
Downloads
6
Comments
0
Likes
2

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Phing for power users Stephan Hochdörfer, bitExpert AG
  • 2. 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
  • 3. Phing for power users I used to be an Ant fanboy...
  • 4. What is Phing? Phing for power users
  • 5. What is Phing? Phing for power users It is a PHP project build system or build tool based on Apache Ant.
  • 6. What is Phing? Phing for power users Domain Specific Language for an project build system.
  • 7. Phing for power users A build system for PHP code? Srsly?
  • 8. Glue for all 3rd party tools Phing for power users
  • 9. How to install Phing? Phing for power users
  • 10. $> pear channel­discover pear.phing.info $> pear install phing/phing How to install Phing? The PEAR way... Phing for power users Installing Phing
  • 11. $> 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:
  • 12. How to install Phing? Phing for power users Installing Phing globally? WTF?!?
  • 13. How to install Phing? Phing for power users Phing is „just another“ dependency for your project.
  • 14. How to install Phing? The Composer way... Phing for power users
  • 15. { "require": { "phing/phing": "2.5.0" } } How to install Phing? The Composer way... Phing for power users composer.json:
  • 16. { "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:
  • 17. 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
  • 18. 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:
  • 19. Phing Basics Phing for power users
  • 20. Phing Basics Phing for power users Project, Target, Task, Properties
  • 21. Phing Basics: Project Phing for power users Root node of a build file containing one or more targets.
  • 22. Phing Basics: Target Phing for power users A group of tasks that run as an entity.
  • 23. Phing Basics: Task Phing for power users Custom piece of code to perform a specific function.
  • 24. Phing Basics: Properties Phing for power users Properties (variables) help to customize execution.
  • 25. Phing Basics: Built-In Properties Phing for power users e.g. host.os, line.separator, phing.version, php.version, …
  • 26. <?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
  • 27. <?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
  • 28. Why Phing? Phing for power users Runs everywhere where PHP runs.
  • 29. Why Phing? Phing for power users No additional depencendies needed (e.g. Java, …).
  • 30. Why Phing? Phing for power users More than 120 predefined tasks to choose from.
  • 31. Why Phing? Phing for power users Easy to extend by writing custom tasks in PHP.
  • 32. Enforce Internal Targets Phing for power users
  • 33. 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>
  • 34. 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
  • 35. 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
  • 36. 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
  • 37. Enforce Internal Targets Phing for power users Internal targets are just helpers like private methods.
  • 38. <?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
  • 39. 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>
  • 40. Enforce Internal Targets – The solution Phing for power users Are the targets really hidden?
  • 41. 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
  • 42. 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
  • 43. 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>
  • 44. $> ./vendor/bin/phing -l Buildfile: /tmp/myproject/build.xml Default target: --------------------------------------------------------- hello Subtargets: --------------------------------------------------------- hello Enforce Internal Targets (Improved Version) Phing for power users
  • 45. Custom Tasks Phing for power users
  • 46. Custom Tasks Phing for power users Phing can do way more than simple exec calls!
  • 47. 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>
  • 48. <?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
  • 49. <?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
  • 50. <?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
  • 51. <?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
  • 52. Properties File Phing for power users
  • 53. Properties File Phing for power users Use properties to cutomize build behaviour.
  • 54. <?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
  • 55. <?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:
  • 56. 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
  • 57. Properties File - Improved version Phing for power users
  • 58. Properties File - Improved version Phing for power users Requirement: Externalize properties but offer customization capabilities!
  • 59. <?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
  • 60. <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
  • 61. $> 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
  • 62. $> 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
  • 63. 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
  • 64. build.properties example Phing for power users Use distinct naming conventions for your properties.
  • 65. Accessing application configuration Phing for power users
  • 66. Accessing application configuration Phing for power users Duplicating configuration code is a bad habit.
  • 67. 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']); } }
  • 68. 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>
  • 69. Imports for Targets can help structuring Phing for power users
  • 70. <?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
  • 71. <?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
  • 72. Import Targets: Path handling Phing for power users Be aware that imports behave like include in PHP!
  • 73. <?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
  • 74. <?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
  • 75. $> ./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
  • 76. Import Targets: Path handling Phing for power users Be aware to always(!) use the projects name in lowercase format!
  • 77. Import Targets: Path handling Phing for power users It`s ${phing.dir.myproject} not ${phing.dir.MyProject}!
  • 78. Distinct Target Naming Phing for power users
  • 79. <?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
  • 80. <?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
  • 81. $> 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
  • 82. 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>
  • 83. Calling PHP functions from Phing Phing for power users
  • 84. 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>
  • 85. Restrict user access Phing for power users
  • 86. <?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
  • 87. Path handling Phing for power users
  • 88. 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>
  • 89. Phing + Jenkins Phing for power users
  • 90. Phing + Jenkins Phing for power users Install the Jenkins Phing plugin
  • 91. Phing for power users
  • 92. Phing for power users
  • 93. Phing for power users
  • 94. Phing + Composer + Jenkins Phing for power users
  • 95. Phing + Composer + Jenkins Phing for power users Install the Jenkins EnvInject plugin
  • 96. Phing for power users
  • 97. Phing for power users
  • 98. Phing for power users
  • 99. Phing for power users
  • 100. Follow conventions Phing for power users
  • 101. Follow conventions Phing for power users Phing expects your build file to be called build.xml and the build’s properties file build.properties
  • 102. Follow conventions Phing for power users Pick meaningful, human-readable names for targets and properties.
  • 103. Follow conventions Phing for power users Make build files self-contained.
  • 104. Thank you!
  • 105. http://joind.in/9023
  • 106. Phing for power users Image Credits http://www.sxc.hu/photo/629370 http://www.sxc.hu/photo/615731