summaryrefslogtreecommitdiff
path: root/buildscripts/phing/pear/BuildPhingPEARPackageTask.php
blob: 6ac6ad51ced0077f7bcfdc9bd9979b4107ee4d4e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
<?php
/*
 *  $Id$
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software consists of voluntary contributions made by many individuals
 * and is licensed under the LGPL. For more information please see
 * <http://phing.info>.
 */

require_once 'phing/tasks/system/MatchingTask.php';
include_once 'phing/types/FileSet.php';
include_once 'phing/tasks/ext/pearpackage/Fileset.php';

/**
 *
 * @author   Hans Lellelid <hans@xmpl.org>
 * @package  phing.tasks.ext
 * @version  $Revision$
 */
class BuildPhingPEARPackageTask extends MatchingTask {

    /** Base directory for reading files. */
    private $dir;

	private $version;
	private $state = 'stable';
	private $notes;
	
	private $filesets = array();
	
    /** Package file */
    private $packageFile;

    public function init() {
        include_once 'PEAR/PackageFileManager2.php';
        if (!class_exists('PEAR_PackageFileManager2')) {
            throw new BuildException("You must have installed PEAR_PackageFileManager2 (PEAR_PackageFileManager >= 1.6.0) in order to create a PEAR package.xml file.");
        }
    }

    private function setOptions($pkg){

		$options['baseinstalldir'] = 'phing';
        $options['packagedirectory'] = $this->dir->getAbsolutePath();

        if (empty($this->filesets)) {
			throw new BuildException("You must use a <fileset> tag to specify the files to include in the package.xml");
		}

		$options['filelistgenerator'] = 'Fileset';

		// Some PHING-specific options needed by our Fileset reader
		$options['phing_project'] = $this->getProject();
		$options['phing_filesets'] = $this->filesets;
		
		if ($this->packageFile !== null) {
            // create one w/ full path
            $f = new PhingFile($this->packageFile->getAbsolutePath());
            $options['packagefile'] = $f->getName();
            // must end in trailing slash
            $options['outputdirectory'] = $f->getParent() . DIRECTORY_SEPARATOR;
            $this->log("Creating package file: " . $f->getPath(), PROJECT_MSG_INFO);
        } else {
            $this->log("Creating [default] package.xml file in base directory.", PROJECT_MSG_INFO);
        }
		
		// add install exceptions
		$options['installexceptions'] = array(	'bin/phing.php' => '/',
												'bin/pear-phing' => '/',
												'bin/pear-phing.bat' => '/',
												);

		$options['dir_roles'] = array(	'phing_guide' => 'doc',
										'etc' => 'data',
										'example' => 'doc');

		$options['exceptions'] = array(	'bin/pear-phing.bat' => 'script',
										'bin/pear-phing' => 'script',
										'CREDITS' => 'doc',
										'CHANGELOG' => 'doc',
										'README' => 'doc',
										'TODO' => 'doc');

		$pkg->setOptions($options);

    }

    /**
     * Main entry point.
     * @return void
     */
    public function main() {

        if ($this->dir === null) {
            throw new BuildException("You must specify the \"dir\" attribute for PEAR package task.");
        }

		if ($this->version === null) {
            throw new BuildException("You must specify the \"version\" attribute for PEAR package task.");
        }

		$package = new PEAR_PackageFileManager2();

		$this->setOptions($package);

		// the hard-coded stuff
		$package->setPackage('phing');
		$package->setSummary('PHP5 project build system based on Apache Ant');
		$package->setDescription('PHing Is Not GNU make; it\'s a project build system based on Apache Ant. 
You can do anything with it that you could do with a traditional build system like GNU make, and its use of 
simple XML build files and extensible PHP "task" classes make it an easy-to-use and highly flexible build framework. 
Features include file transformations (e.g. token replacement, XSLT transformation, Smarty template transformations, 
etc.), file system operations, interactive build support, SQL execution, and much more.');
		$package->setChannel('pear.phing.info');
		$package->setPackageType('php');

		$package->setReleaseVersion($this->version);
		$package->setAPIVersion($this->version);
		
		$package->setReleaseStability($this->state);
		$package->setAPIStability($this->state);
		
		$package->setNotes($this->notes);
		
		$package->setLicense('LGPL', 'http://www.gnu.org/licenses/lgpl.html');
		
		// Add package maintainers
		$package->addMaintainer('lead', 'hans', 'Hans Lellelid', 'hans@xmpl.org');
		$package->addMaintainer('lead', 'mrook', 'Michiel Rook', 'michiel@trendserver.nl');
		
		
		
		// (wow ... this is a poor design ...)
		//
		// note that the order of the method calls below is creating
		// sub-"release" sections which have specific rules.  This replaces
		// the platformexceptions system in the older version of PEAR's package.xml
		//
		// Programmatically, I feel the need to re-iterate that this API for PEAR_PackageFileManager
		// seems really wrong.  Sub-sections should be encapsulated in objects instead of having
		// a "flat" API that does not represent the structure being created....
		
		
		// creating a sub-section for 'windows'
			$package->addRelease();
			$package->setOSInstallCondition('windows');
			$package->addInstallAs('bin/phing.php', 'phing.php');
			$package->addInstallAs('bin/pear-phing.bat', 'phing.bat');
			$package->addIgnoreToRelease('bin/pear-phing');
		
		// creating a sub-section for non-windows
			$package->addRelease();
			//$package->setOSInstallCondition('(*ix|*ux|darwin*|*BSD|SunOS*)');
			$package->addInstallAs('bin/phing.php', 'phing.php');
			$package->addInstallAs('bin/pear-phing', 'phing');
			$package->addIgnoreToRelease('bin/pear-phing.bat');
		

		// "core" dependencies
		$package->setPhpDep('5.0.0');
		$package->setPearinstallerDep('1.4.0');
		
		// "package" dependencies
		$package->addPackageDepWithChannel( 'optional', 'VersionControl_SVN', 'pear.php.net', '0.3.0alpha1');
		$package->addPackageDepWithChannel( 'optional', 'PHPUnit2', 'pear.php.net', '2.3.0');
		$package->addPackageDepWithChannel( 'optional', 'PhpDocumentor', 'pear.php.net', '1.3.0RC3');
		$package->addPackageDepWithChannel( 'optional', 'Xdebug', 'pear.php.net', '2.0.0beta2');
		$package->addPackageDepWithChannel( 'optional', 'Archive_Tar', 'pear.php.net', '1.3.0');
		$package->addPackageDepWithChannel( 'optional', 'PEAR_PackageFileManager', 'pear.php.net', '1.5.2');

		// now add the replacements ....
		$package->addReplacement('Phing.php', 'pear-config', '@DATA-DIR@', 'data_dir');
		$package->addReplacement('bin/pear-phing.bat', 'pear-config', '@PHP-BIN@', 'php_bin');
		$package->addReplacement('bin/pear-phing.bat', 'pear-config', '@BIN-DIR@', 'bin_dir');
		$package->addReplacement('bin/pear-phing.bat', 'pear-config', '@PEAR-DIR@', 'php_dir');
		$package->addReplacement('bin/pear-phing', 'pear-config', '@PHP-BIN@', 'php_bin');
		$package->addReplacement('bin/pear-phing', 'pear-config', '@BIN-DIR@', 'bin_dir');
		$package->addReplacement('bin/pear-phing', 'pear-config', '@PEAR-DIR@', 'php_dir');
		
		// now we run this weird generateContents() method that apparently 
		// is necessary before we can add replacements ... ?
		$package->generateContents();
		
        $e = $package->writePackageFile();

        if (PEAR::isError($e)) {
            throw new BuildException("Unable to write package file.", new Exception($e->getMessage()));
        }

    }

    /**
     * Used by the PEAR_PackageFileManager_PhingFileSet lister.
     * @return array FileSet[]
     */
    public function getFileSets() {
        return $this->filesets;
    }

    // -------------------------------
    // Set properties from XML
    // -------------------------------

    /**
     * Nested creator, creates a FileSet for this task
     *
     * @return FileSet The created fileset object
     */
    function createFileSet() {
        $num = array_push($this->filesets, new FileSet());
        return $this->filesets[$num-1];
    }

	/**
     * Set the version we are building.
     * @param string $v
     * @return void
     */
	public function setVersion($v){
		$this->version = $v;
	}

	/**
     * Set the state we are building.
     * @param string $v
     * @return void
     */
	public function setState($v) {
		$this->state = $v;
	}
	
	/**
	 * Sets release notes field.
	 * @param string $v
	 * @return void
	 */
	public function setNotes($v) {
		$this->notes = $v;
	}
    /**
     * Sets "dir" property from XML.
     * @param PhingFile $f
     * @return void
     */
    public function setDir(PhingFile $f) {
        $this->dir = $f;
    }

    /**
     * Sets the file to use for generated package.xml
     */
    public function setDestFile(PhingFile $f) {
        $this->packageFile = $f;
    }

}