a phing fairy tale - confoo13

76
A Phing fairy tale Stephan Hochdörfer, bitExpert AG

Upload: stephan-hochdoerfer

Post on 09-May-2015

6.234 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: A Phing fairy tale - ConFoo13

A Phing fairy taleStephan Hochdörfer, bitExpert AG

Page 2: A Phing fairy tale - ConFoo13

A Phing fairy tale

About me

Stephan Hochdörfer

Head of IT at bitExpert AG, Germany

enjoying PHP since 1999

[email protected]

@shochdoerfer

Page 3: A Phing fairy tale - ConFoo13

Disclaimer

A Phing fairy tale

Warning: You will see a hell lot of XML.

Page 4: A Phing fairy tale - ConFoo13

What is Phing?

A Phing fairy tale

Page 5: A Phing fairy tale - ConFoo13

What is Phing?

A Phing fairy tale

It is a PHP project build system or build tool based on Apache Ant.

Page 6: A Phing fairy tale - ConFoo13

What is Phing?

A Phing fairy tale

Domain Specific Language for an project build system.

Page 7: A Phing fairy tale - ConFoo13

What is Phing?

A Phing fairy tale

Enables one button push automation.

Page 8: A Phing fairy tale - ConFoo13

Project build system?

A Phing fairy tale

Page 9: A Phing fairy tale - ConFoo13

Project build system?

A Phing fairy tale

Automation of non-development tasks

Page 10: A Phing fairy tale - ConFoo13

Project build system?

A Phing fairy tale

Automate absolutely everything.

Page 11: A Phing fairy tale - ConFoo13

Project build system?

A Phing fairy tale

If you use Phing, only use Phing.

Page 12: A Phing fairy tale - ConFoo13

Why Phing?

A Phing fairy tale

Page 13: A Phing fairy tale - ConFoo13

Why Phing?

A Phing fairy tale

Runs everywhere where PHP runs.

Page 14: A Phing fairy tale - ConFoo13

Why Phing?

A Phing fairy tale

No additional depencendies needed(e.g. Java, …).

Page 15: A Phing fairy tale - ConFoo13

Why Phing?

A Phing fairy tale

More than 120 predefinedtasks to choose from.

Page 16: A Phing fairy tale - ConFoo13

Why Phing?

A Phing fairy tale

Easy to extend by writing custom tasks in PHP.

Page 17: A Phing fairy tale - ConFoo13

How to install Phing?

A Phing fairy tale

Page 18: A Phing fairy tale - ConFoo13

$> pear channel­discover pear.phing.info$> pear install phing/phing

How to install Phing? The PEAR way...

A Phing fairy tale

Installing Phing

Page 19: A Phing fairy tale - ConFoo13

$> phing ­vPhing 2.4.14

$> pear channel­discover pear.phing.info$> pear install phing/phing

How to install Phing? The PEAR way...

A Phing fairy tale

Installing Phing

Running Phing:

Page 20: A Phing fairy tale - ConFoo13

{"require": {

"phing/phing": "2.4.14"}

}

How to install Phing? The Composer way...

A Phing fairy tale

composer.json:

Page 21: A Phing fairy tale - ConFoo13

$> php composer.phar installLoading composer repositories with package informationInstalling dependencies  ­ Installing phing/phing (2.4.14)    Downloading: 100%         

Writing lock fileGenerating autoload files

{"require": {

"phing/phing": "2.4.14"}

}

How to install Phing? The Composer way...

A Phing fairy tale

composer.json:

Running Composer:

Page 22: A Phing fairy tale - ConFoo13

How to install Phing? The Composer way...

A Phing fairy tale

/home/shochdoerfer/myproject   |­vendor   |­­­bin   |­­­­­@phing   |­­­composer   |­­­phing   |­­­­­phing   |­­­­­­­bin   |­­­­­­­­­phing   |­­­­­­­build   |­­­­­­­classes   |­­­­­­­docs   |­­­­­­­etc   |­­­­­­­test

Page 23: A Phing fairy tale - ConFoo13

How to install Phing? The Composer way...

A Phing fairy tale

/home/shochdoerfer/myproject   |­vendor   |­­­bin   |­­­­­@phing   |­­­composer   |­­­phing   |­­­­­phing   |­­­­­­­bin   |­­­­­­­­­phing   |­­­­­­­build   |­­­­­­­classes   |­­­­­­­docs   |­­­­­­­etc   |­­­­­­­test

$> ./vendor/bin/phing ­vPhing DEV

Running Phing:

Page 24: A Phing fairy tale - ConFoo13

Phing Basics

A Phing fairy tale

Page 25: A Phing fairy tale - ConFoo13

Phing Basics

A Phing fairy tale

Project, Target, Task, Properties

Page 26: A Phing fairy tale - ConFoo13

Phing Basics: Project

A Phing fairy tale

Root node of a build file containing one or more targets.

Page 27: A Phing fairy tale - ConFoo13

Phing Basics: Target

A Phing fairy tale

A group of tasks that run as an entity.

Page 28: A Phing fairy tale - ConFoo13

Phing Basics: Task

A Phing fairy tale

Custom piece of code to perform a specific function.

Page 29: A Phing fairy tale - ConFoo13

Phing Basics: Properties

A Phing fairy tale

Properties (Variables) help to customize execution.

Page 30: A Phing fairy tale - ConFoo13

Phing Basics: Built-In Properties

A Phing fairy tale

e.g. host.os, line.separator, phing.version, php.version, …

Page 31: A Phing fairy tale - ConFoo13

<?xml version="1.0"?><project name="myproject" default="init">

<target name="init">

<!­­ insert logic here ­­></target>

</project>

Phing Basics: Sample Build File

A Phing fairy tale

Page 32: A Phing fairy tale - ConFoo13

<?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

A Phing fairy tale

Page 33: A Phing fairy tale - ConFoo13

<?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

A Phing fairy tale

$> phingBuildfile: /home/shochdoerfer/build.xml

myproject > hello:

     [echo] Hello, world!

BUILD FINISHED

Total time: 0.0595 seconds

Page 34: A Phing fairy tale - ConFoo13

<?xml version="1.0"?><project name="myproject" default="hello">

<target name="hello" description="Says Hello, world!">

 <property name="Hello"                 value="Hello, world!" />

 <echo msg="${Hello}" /></target>

</project>

Build File – Introducing Properties

A Phing fairy tale

Page 35: A Phing fairy tale - ConFoo13

<?xml version="1.0"?><project name="myproject" default="hello">

<property name="Hello" value="Hello, world!" /> <target name="hello" 

description="Says Hello, world!">

 <echo msg="${Hello}" /></target>

</project>

Build File – Introducing Properties

A Phing fairy tale

Page 36: A Phing fairy tale - ConFoo13

<?xml version="1.0"?><project name="myproject" default="hello">

<target name="hello" description="Says whatever you want to say"

 <echo msg="${Hello}" /></target>

</project>

Build File – Externalizing Properties

A Phing fairy tale

Page 37: A Phing fairy tale - ConFoo13

<?xml version="1.0"?><project name="myproject" default="hello">

<target name="hello" description="Says whatever you want to say"

 <echo msg="${Hello}" /></target>

</project>

Build File – Externalizing Properties (CLI)

A Phing fairy tale

$> phing ­DHello="Hello from CLI"Buildfile: /tmp/build.xml

myproject > hello:

     [echo] Hello from CLI

BUILD FINISHED

Total time: 0.0599 seconds

Page 38: A Phing fairy tale - ConFoo13

<?xml version="1.0"?><project name="myproject" default="hello">

<target name="hello" description="Says whatever you want to say">

<propertyfile="./build.properties" />

 <echo msg="${Hello}" /></target>

</project>

Build File – Externalizing Properties (File)

A Phing fairy tale

Page 39: A Phing fairy tale - ConFoo13

<?xml version="1.0"?><project name="myproject" default="hello">

<target name="hello" description="Says whatever you want to say">

<propertyfile="./build.properties" />

 <echo msg="${Hello}" /></target>

</project>

Build File – Externalizing Properties (File)

A Phing fairy tale

Hello=Hello, world!build.properties:

Page 40: A Phing fairy tale - ConFoo13

$> phingBuildfile: /home/shochdoerfer/build.xml

myproject > hello:

 [property] Loading /home/shochdoerfer/build.properties     [echo] Hello, world!

BUILD FINISHED

Total time: 0.0601 seconds

Build File – Externalizing Properties (File)

A Phing fairy tale

Page 41: A Phing fairy tale - ConFoo13

<?xml version="1.0"?><project name="myproject" default="hello">

<property name="Hello" value="Hello, world!" /> <target name="hello" 

description="Says Hello, world!">

 <echo msg="${Hello}" /></target>

<target name="goodbye" description="Says goodbye!">

 <echo msg="Goodbye!" /></target>

</project>

Build File – Defining multiple targets

A Phing fairy tale

Page 42: A Phing fairy tale - ConFoo13

$> phing helloBuildfile: /tmp/build.xml

myproject > hello:

     [echo] Hello, world!

BUILD FINISHED

Total time: 0.0612 seconds

Build File – Defining multiple targets

A Phing fairy tale

Page 43: A Phing fairy tale - ConFoo13

$> phing helloBuildfile: /tmp/build.xml

myproject > hello:

     [echo] Hello, world!

BUILD FINISHED

Total time: 0.0612 seconds

$> phing goodbyeBuildfile: /tmp/build.xml

myproject > goodbye:

     [echo] Goodbye!

BUILD FINISHED

Total time: 0.0619 seconds

Build File – Defining multiple targets

A Phing fairy tale

Page 44: A Phing fairy tale - ConFoo13

<?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>

Build File – Target dependencies

A Phing fairy tale

Page 45: A Phing fairy tale - ConFoo13

<?xml version="1.0"?><project name="myproject" default="hello">

<target name="init" description="Property initialization">

<property name="Hello" value="Hello, world!" /></target>

<target name="customcode" description="Some custom logic">

</target>

<target name="hello" depends="init, customcode">

 <echo msg="${Hello}" /></target>

</project>

Build File – Target dependencies

A Phing fairy tale

Page 46: A Phing fairy tale - ConFoo13

<?xml version="1.0"?><project name="myproject" default="hello">

<target name="pre­init"><property name="World" value="world" />

</target>

<target name="init" depends="pre­init"><property name="Hello" 

               value="Hello, ${World}!" /></target>

<target name="hello" depends="init">

 <echo msg="${Hello}" /></target>

</project>

Build File – Target dependencies

A Phing fairy tale

Page 47: A Phing fairy tale - ConFoo13

<?xml version="1.0"?><project name="myproject" default="run">

<target name="print"><echo msg="Processing: ${filename}" />

</target>

<target name="run"><!­­ 

           loop through files and call print target ­­><foreach param="filename" 

             absparam="filename" target="print">

<fileset dir="."><include name="*.php"/>

</fileset></foreach>

</target></project>

Build File – Calling targets programmatically I

A Phing fairy tale

Page 48: A Phing fairy tale - ConFoo13

<?xml version="1.0"?><project name="myproject" default="run">

<target name="print"><echo msg="Processing: ${filename}" />

</target>

<target name="run">

<!­­ calling target with given property ­­><phingcall target="print">

<property name="filename"                   value="test.php" />

</phingcall></target>

</project>

Build File – Calling targets programmatically II

A Phing fairy tale

Page 49: A Phing fairy tale - ConFoo13

<?xml version="1.0"?><project name="myproject" default="run">

<target name="run">

<!­­ calling target in print.xml with               given property ­­>

<phing phingfile="print.xml" target="print"><property name="filename" 

                 value="test.php" /></phing>

</target></project>

Build File – Calling targets programmatically III

A Phing fairy tale

Page 50: A Phing fairy tale - ConFoo13

<?xml version="1.0"?><project name="myproject" default="run">

<target name="run">

      <!­­ Copy files matching the expression ­­>      <copy todir="/tmp/deploy">

<fileset dir="." includes="**/*.php"><and>

<size value="1024" when="more" /><date 

                          datetime="01/01/2013 10:00 AM"                           when="after" />

</and></fileset>

      </copy></target>

</project>

Build File – Fileset

A Phing fairy tale

Page 51: A Phing fairy tale - ConFoo13

<?xml version="1.0"?><project name="myproject" default="run">

<target name="run">      <!­­ Copy files and replace tokens ­­>      <copy todir="/tmp/deploy">

<filterchain><replacetokens begintoken="##"

                       endtoken="##"><token key="VERSION" 

                              value="${app.version}"</replacetokens>

</filterchain>

<fileset dir=".">      <include name="**/*.php"/></fileset>

      </copy></target>

</project>

Build File – Filters

A Phing fairy tale

Page 52: A Phing fairy tale - ConFoo13

Phing – What can it do for me?

A Phing fairy tale

Page 53: A Phing fairy tale - ConFoo13

<?xml version="1.0"?><project name="myproject" default="run">

<target name="run">      <!­­ correct file permissions ­­>            <chmod file="${project.basedir}/cache" 

                  mode="0777" />            <chmod file="${project.basedir}/uploads" 

                  mode="0777" /></target>

</project>

Phing – What can it do for me?

A Phing fairy tale

Page 54: A Phing fairy tale - ConFoo13

<?xml version="1.0"?><project name="myproject" default="run">

<target name="run">      <!­­ create API documentation ­­>            <docblox title="My project"

              destdir="apidocs"           template="new_black">

      <fileset dir="${project.basedir}/src">          <include name="**/*.php" />      </fileset>

      </docblox></target>

</project>

Phing – What can it do for me?

A Phing fairy tale

Page 55: A Phing fairy tale - ConFoo13

<?xml version="1.0"?><project name="myproject" default="run">

<target name="run">      <!­­ minify javascript ­­>

      <jsMin targetDir="${project.basedir}/web/"><fileset dir="${project.basedir}/web/js/">

<include name="**/*.js"/></fileset>

      </jsMin></target>

</project>

Phing – What can it do for me?

A Phing fairy tale

Page 56: A Phing fairy tale - ConFoo13

<?xml version="1.0"?><project name="myproject" default="run">

<target name="run">      <!­­ exec database migrations ­­>

     <liquibase­update    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>

Phing – What can it do for me?

A Phing fairy tale

Page 57: A Phing fairy tale - ConFoo13

<?xml version="1.0"?><project name="myproject" default="run">

<target name="run">      <!­­ deploy via rsync to dev server ­­>

     <exec     command="rsync ­vraCz ./ ${deploy.dev.url}"     dir="${project.basedir}"     checkreturn="true" />

</target></project>

Phing – Task missing? Use exec...

A Phing fairy tale

Page 58: A Phing fairy tale - ConFoo13

Build File – Advanced usage

A Phing fairy tale

Page 59: A Phing fairy tale - ConFoo13

<?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="Load default build.properties"<property

file="./build.properties" /></target>

Properties File - Improved version

A Phing fairy tale

Page 60: A Phing fairy tale - ConFoo13

<target name="local­prop"if="local­prop.exists"depends="local­prop­check">

<echo message="Loading custom properties!"<property

file="${project.basedir}/local.properties"override="true"/>

</target>

<target name="local­prop­check"><available

file="${project.basedir}/local.properties"property="local­prop.exists" />

</target></project>

Properties File - Improved version

A Phing fairy tale

Page 61: A Phing fairy tale - ConFoo13

<?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

A Phing fairy tale

User can call both targets from command line. We do not want that.

Page 62: A Phing fairy tale - ConFoo13

<?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

A Phing fairy tale

Prefixing a targets with a „-“ prevents the target from being called from the command line.

Page 63: A Phing fairy tale - ConFoo13

<?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>

Custom Task (Adhoc definition)

A Phing fairy tale

Page 64: A Phing fairy tale - ConFoo13

<?phprequire_once 'phing/Task.php';

class MyTask extends Task {/** * (non­PHPdoc) * @see \Task::main() */public function main() {

// Custom code here...}

}

Custom Task (External file)

A Phing fairy tale

Page 65: A Phing fairy tale - ConFoo13

<?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)

A Phing fairy tale

Page 66: A Phing fairy tale - ConFoo13

<?phprequire_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

A Phing fairy tale

Page 67: A Phing fairy tale - ConFoo13

<?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

A Phing fairy tale

Page 68: A Phing fairy tale - ConFoo13

<?xml version="1.0"?><project name="myproject" default="app:run">

<!­­The following target namespaces exist:db:*  ­ Database specific targetsapp:* ­ Application specific tasksci:*  ­ 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

A Phing fairy tale

Page 69: A Phing fairy tale - ConFoo13

<?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

A Phing fairy tale

Page 70: A Phing fairy tale - ConFoo13

<?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>

Prompt user for input

A Phing fairy tale

Page 71: A Phing fairy tale - ConFoo13

<?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>

Calling PHP functions from Phing

A Phing fairy tale

Page 72: A Phing fairy tale - ConFoo13

Follow conventions

A Phing fairy tale

Phing expects your build file to be called build.xml and the build’s properties file

build.properties

Page 73: A Phing fairy tale - ConFoo13

Follow conventions

A Phing fairy tale

Pick meaningful, human-readable names for targets and properties.

Page 74: A Phing fairy tale - ConFoo13

Follow conventions

A Phing fairy tale

Make build files self-contained.

Page 75: A Phing fairy tale - ConFoo13

Thank you!

Page 76: A Phing fairy tale - ConFoo13

http://joind.in/7949