The main entry point

@throws BuildException
429861
public function main()
    {
        $this->setup('switch');

        $this->log(
            "Switching SVN repository at '" . $this->getToDir() . "' to '" . $this->getRepositoryUrl() . "' "
            . ($this->getRevision() == 'HEAD' ? '' : " (revision: {$this->getRevision()})")
        );

        // revision
        $switches = [
            'r' => $this->getRevision(),
        ];

        $this->run([$this->getToDir()], $switches);
    }
1280154
public function main()
    {
        if (null === $this->getRepository()) {
            throw new BuildException('"repository" is required parameter');
        }

        if (null === $this->getTargetPath()) {
            throw new BuildException('"targetPath" is required parameter');
        }

        $files = @scandir($this->getTargetPath());
        if (isset($files) && is_array($files) && (count($files) > 2)) {
            throw new BuildException(
                sprintf(
                    '"%s" target directory is not empty',
                    $this->getTargetPath()
                )
            );
        }

        try {
            $this->doClone($this->getGitClient(false, getcwd()));
        } catch (Exception $e) {
            throw new BuildException('The remote end hung up unexpectedly', $e);
        }

        $msg = 'git-clone: cloning '
            . ($this->isBare() ? '(bare) ' : '')
            . ($this->hasDepth() ? ' (depth="' . $this->getDepth() . '") ' : '')
            . '"' . $this->getRepository() . '" repository'
            . ' to "' . $this->getTargetPath() . '" directory';
        $this->log($msg, Project::MSG_INFO);
    }
939182
public function main()
    {
        $clone = $this->getFactoryInstance('tag');
        $cwd = getcwd();

        if ($this->name === '') {
            throw new BuildException("Tag name must be set.");
        }
        if ($this->repository === '') {
            $prog = $this->getProject();
            $dir = $prog->getProperty('application.startdir');
        } else {
            $dir = $this->repository;
        }

        if ($this->revision !== '') {
            $clone->setRev($this->revision);
        }
        if ($this->user !== null) {
            $clone->setUser($this->user);
        }
        $message = $this->getMessage();
        $clone->setMessage($message);
        $name = $this->getName();
        if ($name == '') {
            throw new BuildException("Name attribute must be set.");
        }
        $clone->addName($name);

        $this->checkRepositoryIsDirAndExists($dir);
        chdir($dir);

        try {
            $this->log("Executing: " . $clone, Project::MSG_INFO);
            $output = $clone->execute();
            if ($output !== '') {
                $this->log($output);
            }
        } catch (Exception $ex) {
            $msg = $ex->getMessage();
            $p = strpos($msg, 'hg returned:');
            if ($p !== false) {
                $msg = substr($msg, $p + 13);
            }
            chdir($cwd);
            throw new BuildException($msg);
        }
        chdir($cwd);
    }
767032
public function main()
    {
        if (null === $this->getRepository()) {
            throw new BuildException('"repository" is required parameter');
        }

        $client = $this->getGitClient(false, $this->getRepository());
        $command = $client->getCommand('log');
        $command
            ->setOption('stat', $this->getStat())
            ->setOption('name-status', $this->isNameStatus())
            ->setOption('no-merges', $this->isNoMerges())
            ->setOption('format', $this->getFormat());

        if (null !== $this->getMaxCount()) {
            $command->setOption('max-count', $this->getMaxCount());
        }

        if (null !== $this->getDate()) {
            $command->setOption('date', $this->getDate());
        }

        if (null !== $this->getSince()) {
            $command->setOption('since', $this->getSince());
        }

        if (null !== $this->getUntil()) {
            $command->setOption('until', $this->getUntil());
        }

        $command->addDoubleDash(true);
        if (null !== $this->getPaths()) {
            $command->addDoubleDash(false);
            $paths = explode(PATH_SEPARATOR, $this->getPaths());
            foreach ($paths as $path) {
                $command->addArgument($path);
            }
        }

        $this->log('git-log command: ' . $command->createCommandString(), Project::MSG_INFO);

        try {
            $output = $command->execute();
        } catch (Exception $e) {
            throw new BuildException('Task execution failed', $e);
        }

        if (null !== $this->outputProperty) {
            $this->project->setProperty($this->outputProperty, trim($output));
        }

        $this->log(
            sprintf('git-log: commit log for "%s" repository', $this->getRepository()),
            Project::MSG_INFO
        );
        $this->log('git-log output: ' . trim($output), Project::MSG_INFO);
    }
20813
public function main()
    {
        if (null === $this->getRepository()) {
            throw new BuildException('"repository" is required parameter');
        }

        $client = $this->getGitClient(false, $this->getRepository());
        $command = $client->getCommand('fetch');
        $command
            ->setOption('tags', $this->isTags())
            ->setOption('no-tags', $this->isNoTags())
            ->setOption('prune', $this->isPrune())
            ->setOption('keep', $this->isKeepFiles())
            ->setOption('q', $this->isQuiet())
            ->setOption('force', $this->isForce());

        // set operation target
        if ($this->isAllRemotes()) { // --all
            $command->setOption('all', true);
        } elseif ($this->getGroup()) { // <group>
            $command->addArgument($this->getGroup());
        } elseif ($this->getSource()) { // <repository> [<refspec>]
            $command->addArgument($this->getSource());
            if ($this->getRefspec()) {
                $command->addArgument($this->getRefspec());
            }
        } else {
            throw new BuildException('No remote repository specified');
        }

        $this->log('git-fetch command: ' . $command->createCommandString(), Project::MSG_INFO);

        try {
            $output = $command->execute();
        } catch (Exception $e) {
            throw new BuildException('Task execution failed.', $e);
        }

        $this->log(
            sprintf('git-fetch: branch "%s" repository', $this->getRepository()),
            Project::MSG_INFO
        );
        $this->log('git-fetch output: ' . trim($output), Project::MSG_INFO);
    }
1310614
public function main()
    {
        if ($this->dir === null) {
            throw new BuildException("dir attribute is required", $this->getLocation());
        }
        if ($this->dir->isFile()) {
            throw new BuildException(
                "Unable to create directory as a file already exists with that name: " . $this->dir->getAbsolutePath()
            );
        }
        if (!$this->dir->exists()) {
            $result = $this->dir->mkdirs($this->mode);
            if (!$result) {
                if ($this->dir->exists()) {
                    $this->log("A different process or task has already created " . $this->dir->getAbsolutePath());

                    return;
                }
                $msg = "Directory " . $this->dir->getAbsolutePath() . " creation was not successful for an unknown reason";
                throw new BuildException($msg, $this->getLocation());
            }
            $this->log("Created dir: " . $this->dir->getAbsolutePath());
        }
    }
866987
public function main()
    {
        // Check to make sure the input and output files were specified and that the input file exists.

        if (!$this->xmlConfFile || !$this->xmlConfFile->exists()) {
            throw new BuildException("No valid xmlConfFile specified.", $this->getLocation());
        }

        if (!$this->outputFile) {
            throw new BuildException("No outputFile specified.", $this->getLocation());
        }

        $this->log('Loading XML configuration file...');

        // Create a PHP array from the runtime-conf.xml file
        $xmlDom = new DOMDocument();
        $xmlDom->load($this->xmlConfFile->getAbsolutePath());
        $xml = simplexml_load_string($xmlDom->saveXML());
        $phpconf = self::simpleXmlToArray($xml);
        $this->log(sprintf('Loaded "%s" successfully', $this->xmlConfFile->getAbsolutePath()), Project::MSG_VERBOSE);

        /* For some reason the array generated from runtime-conf.xml has separate
         * 'log' section and 'propel' sections. To maintain backward compatibility
         * we need to put 'log' back into the 'propel' section.
         */
        $log = array();
        if (isset($phpconf['log'])) {
            $phpconf['propel']['log'] = $phpconf['log'];
            unset($phpconf['log']);
        }

        if (isset($phpconf['propel'])) {
            $phpconf = $phpconf['propel'];
        }

        // add generator version
        $phpconf['generator_version'] = $this->getGeneratorConfig()->getBuildProperty('version');

        if (!$this->outputClassmapFile) {
            // We'll create a default one for BC
            $this->outputClassmapFile = 'classmap-' . $this->outputFile;
        }

        // Write resulting PHP data to output file
        $outfile = new PhingFile($this->outputDirectory, $this->outputFile);
        $output = "<?php\n";
        $output .= "// This file generated by Propel " . $phpconf['generator_version'] . " convert-conf target" . ($this->getGeneratorConfig()->getBuildProperty('addTimestamp') ? " on " . strftime("%c") : '') . "\n";
        $output .= "// from XML runtime conf file " . $this->xmlConfFile->getPath() . "\n";
        $output .= "\$conf = ";
        $output .= var_export($phpconf, true);
        $output .= ";\n";
        $output .= "\$conf['classmap'] = include(dirname(__FILE__) . DIRECTORY_SEPARATOR . '" . $this->outputClassmapFile . "');\n";
        $output .= "return \$conf;";

        $mustWriteRuntimeConf = true;
        if (file_exists($outfile->getAbsolutePath())) {
            $currentRuntimeConf = file_get_contents($outfile->getAbsolutePath());
            if ($currentRuntimeConf == $output) {
                $this->log(sprintf('No change in PHP runtime conf file "%s"', $outfile->getPath()), Project::MSG_VERBOSE);
                $mustWriteRuntimeConf = false;
            } else {
                $this->log(sprintf('Updating PHP runtime conf file "%s"', $outfile->getPath()));
            }
        } else {
            $this->log(sprintf('Creating PHP runtime conf file "%s"', $outfile->getPath()));
        }
        if ($mustWriteRuntimeConf && !file_put_contents($outfile->getAbsolutePath(), $output)) {
            throw new BuildException("Error writing output file: " . $outfile->getAbsolutePath(), $this->getLocation());
        }

        // add classmap
        $phpconfClassmap = $this->getClassMap();
        $outfile = new PhingFile($this->outputDirectory, $this->outputClassmapFile);
        $output = '<' . '?' . "php\n";
        $output .= "// This file generated by Propel " . $phpconf['generator_version'] . " convert-conf target" . ($this->getGeneratorConfig()->getBuildProperty('addTimestamp') ? " on " . strftime("%c") : '') . "\n";
        $output .= "return ";
        $output .= var_export($phpconfClassmap, true);
        $output .= ";";

        $mustWriteClassMap = true;
        if (file_exists($outfile->getAbsolutePath())) {
            $currentClassmap = file_get_contents($outfile->getAbsolutePath());
            if ($currentClassmap == $output) {
                $this->log(sprintf('No change in PHP classmap file "%s"', $outfile->getPath()), Project::MSG_VERBOSE);
                $mustWriteClassMap = false;
            } else {
                $currentPhpconfClassmap = include $outfile->getAbsolutePath();
                if ($addedMaps = array_diff_assoc($phpconfClassmap, $currentPhpconfClassmap)) {
                    $this->log('Added classmap for the following classes:', Project::MSG_VERBOSE);
                    $this->logClassMap($addedMaps);
                }
                if ($removedMaps = array_diff_assoc($currentPhpconfClassmap, $phpconfClassmap)) {
                    $this->log('Removed classmap for the following classes:', Project::MSG_VERBOSE);
                    $this->logClassMap($removedMaps);
                }
                $this->log(sprintf('Updating PHP classmap file "%s"', $outfile->getPath()));
            }
        } else {
            $this->log(sprintf('Creating PHP classmap file "%s"', $outfile->getPath()));
            $this->logClassMap($phpconfClassmap);
        }
        if ($mustWriteClassMap && !file_put_contents($outfile->getAbsolutePath(), $output)) {
            throw new BuildException("Error writing output file: " . $outfile->getAbsolutePath(), $this->getLocation());
        }

        if (!$mustWriteRuntimeConf && !$mustWriteClassMap) {
            $this->log('No change in compiled configuration files');
        }
    }
407449
public function main()
    {
        $message = $this->getMessage();
        if ($message === '') {
            throw new BuildException('"message" is a required parameter');
        }

        $user = $this->getUser();

        $clone = $this->getFactoryInstance('commit');
        $msg = sprintf("Commit: '%s'", $message);
        $this->log($msg, Project::MSG_INFO);
        $clone->setQuiet($this->getQuiet());
        $clone->setMessage($message);

        if (trim($user) === "") {
            throw new BuildException('"user" parameter can not be set to ""');
        }
        if ($user !== null) {
            $clone->setUser($user);
            $this->log("Commit: user = '$user'", Project::MSG_VERBOSE);
        }

        if ($this->repository === '') {
            $project = $this->getProject();
            $dir = $project->getProperty('application.startdir');
        } else {
            $dir = $this->repository;
        }
        $this->log('DIR:' . $dir, Project::MSG_INFO);
        $this->log('REPO: ' . $this->repository, Project::MSG_INFO);
        $cwd = getcwd();
        chdir($dir);

        try {
            $this->log("Executing: " . $clone->asString(), Project::MSG_INFO);
            $output = $clone->execute();
            if ($output !== '') {
                $this->log($output);
            }
        } catch (Exception $ex) {
            $msg = $ex->getMessage();
            $this->log("Exception: $msg", Project::MSG_INFO);
            $p = strpos($msg, 'hg returned:');
            if ($p !== false) {
                $msg = substr($msg, $p + 13);
            }
            chdir($cwd);
            throw new BuildException($msg);
        }
        chdir($cwd);
    }
419084
public function main()
    {
        $clone = $this->getFactoryInstance('pull');
        $clone->setInsecure($this->getInsecure());
        $clone->setQuiet($this->getQuiet());

        $cwd = getcwd();

        if ($this->repository === '') {
            $project = $this->getProject();
            $dir = $project->getProperty('application.startdir');
        } else {
            $dir = $this->repository;
        }
        $this->checkRepositoryIsDirAndExists($dir);
        chdir($dir);

        try {
            $this->log("Executing: " . $clone->asString(), Project::MSG_INFO);
            $output = $clone->execute();
            if ($output !== '') {
                $this->log($output);
            }
        } catch (Exception $ex) {
            $msg = $ex->getMessage();
            $p = strpos($msg, 'hg returned:');
            if ($p !== false) {
                $msg = substr($msg, $p + 13);
            }
            chdir($cwd);
            throw new BuildException($msg);
        }
        chdir($cwd);
    }
189542
public function main()
    {
        if (!isset($this->file) and count($this->filesets) == 0) {
            throw new BuildException("Missing either a nested fileset or attribute 'file' set");
        }

        if (empty($this->executable)) {
            throw new BuildException("Missing the 'executable' attribute");
        }

        if ($this->file instanceof PhingFile) {
            $this->lint($this->file->getPath());
        } else { // process filesets
            $project = $this->getProject();
            foreach ($this->filesets as $fs) {
                $ds = $fs->getDirectoryScanner($project);
                $files = $ds->getIncludedFiles();
                $dir = $fs->getDir($this->project)->getPath();
                foreach ($files as $file) {
                    $this->lint($dir . DIRECTORY_SEPARATOR . $file);
                }
            }
        }

        // write list of 'bad files' to file (if specified)
        if ($this->tofile) {
            $writer = new FileWriter($this->tofile);

            foreach ($this->badFiles as $file => $messages) {
                foreach ($messages as $msg) {
                    $writer->write($file . "=" . $msg . PHP_EOL);
                }
            }

            $writer->close();
        }

        if ($this->haltOnFailure && $this->hasErrors) {
            throw new BuildException(
                'Syntax error(s) in JS files:' . implode(
                    ', ',
                    array_keys($this->badFiles)
                )
            );
        }
        if ($this->haltOnWarning && $this->hasWarnings) {
            throw new BuildException(
                'Syntax warning(s) in JS files:' . implode(
                    ', ',
                    array_keys($this->badFiles)
                )
            );
        }
    }
627587
public function main()
    {
        if (!extension_loaded('zip')) {
            throw new BuildException("Zip extension is required");
        }

        if ($this->zipFile === null) {
            throw new BuildException("zipfile attribute must be set!", $this->getLocation());
        }

        if ($this->zipFile->exists() && $this->zipFile->isDirectory()) {
            throw new BuildException("zipfile is a directory!", $this->getLocation());
        }

        if ($this->zipFile->exists() && !$this->zipFile->canWrite()) {
            throw new BuildException("Can not write to the specified zipfile!", $this->getLocation());
        }

        try {
            if ($this->baseDir !== null) {
                if (!$this->baseDir->exists()) {
                    throw new BuildException(
                        "basedir '" . (string) $this->baseDir . "' does not exist!",
                        $this->getLocation()
                    );
                }

                if (empty($this->filesets)) {
                    // add the main fileset to the list of filesets to process.
                    $mainFileSet = $this->fileset;
                    $mainFileSet->setDir($this->baseDir);
                    $this->filesets[] = $mainFileSet;
                }
            }

            if (empty($this->filesets)) {
                throw new BuildException(
                    "You must supply either a basedir "
                    . "attribute or some nested filesets.",
                    $this->getLocation()
                );
            }

            // check if zip is out of date with respect to each
            // fileset
            if ($this->areFilesetsUpToDate()) {
                $this->log("Nothing to do: " . $this->zipFile->__toString() . " is up to date.", Project::MSG_INFO);

                return;
            }

            $this->log("Building zip: " . $this->zipFile->__toString(), Project::MSG_INFO);

            $zip = new ZipArchive();
            $res = $zip->open($this->zipFile->getAbsolutePath(), ZipArchive::CREATE);

            if ($res !== true) {
                throw new Exception("ZipArchive::open() failed with code " . $res);
            }

            if ($this->comment !== '') {
                $isCommented = $zip->setArchiveComment($this->comment);
                if ($isCommented === false) {
                    $this->log("Could not add a comment for the Archive.", Project::MSG_INFO);
                }
            }

            $this->addFilesetsToArchive($zip);

            $zip->close();
        } catch (IOException $ioe) {
            $msg = "Problem creating ZIP: " . $ioe->getMessage();
            throw new BuildException($msg, $ioe, $this->getLocation());
        }
    }
1002361
public function main()
    {
        $this->checkFile();
        $this->checkPropertyName();

        $size = filesize($this->file);

        if ($size === false) {
            throw new BuildException(sprintf('[FileSize] Cannot determine size of file: %s', $this->file));
        }

        // publish hash value
        $this->project->setProperty($this->propertyName, $size);
    }
833991
public function main()
    {
        if ($this->realThing === null) {
            // plain impossible to get here, maybeConfigure should
            // have thrown an exception.
            throw new BuildException("Should not be executing UnknownElement::main() -- task/type: {$this->elementName}");
        }

        if ($this->realThing instanceof Task) {
            $this->realThing->main();
        }
    }
170398
public function main()
    {
        if ($this->composer === null) {
            $this->findComposer();
        }

        $files = array();
        if (!empty($this->file) && file_exists($this->file)) {
            $files[] = $this->file;
        }

        if (!empty($this->dir)) {
            $found = $this->findFiles();
            foreach ($found as $file) {
                $files[] = $this->dir . DIRECTORY_SEPARATOR . $file;
            }
        }

        foreach ($files as $file) {

            $cmd = $this->composer . ' validate ' . $file;
            $cmd = escapeshellcmd($cmd);

            if ($this->passthru) {
                $retval = null;
                passthru($cmd, $retval);
                if ($retval == 1) {
                    throw new BuildException('invalid composer.json');
                }
            } else {
                $out = array();
                $retval = null;
                exec($cmd, $out, $retval);
                if ($retval == 1) {
                    $err = join("\n", $out);
                    throw new BuildException($err);
                } else {
                    $this->log($out[0]);
                }
            }

        }

    }
170432
public function main()
    {

        // Make sure the template path is set.
        if (empty($this->templatePath)) {
            throw new BuildException("The template path needs to be defined!");
        }

        // Make sure the control template is set.
        if ($this->controlTemplate === null) {
            throw new BuildException("The control template needs to be defined!");
        }

        // Make sure the output directory is set.
        if ($this->outputDirectory === null) {
            throw new BuildException("The output directory needs to be defined!");
        }

        // Make sure there is an output file.
        if ($this->outputFile === null) {
            throw new BuildException("The output file needs to be defined!");
        }

        // Setup Smarty runtime.

        // Smarty uses one object to store properties and to store
        // the context for the template (unlike Smarty).  We setup this object, calling it
        // $this->context, and then initControlContext simply zeros out
        // any assigned variables.
        //
        // Use the smarty backwards compatibility layer if existent.
        if (class_exists('SmartyBC')) {
            $this->context = new SmartyBC();
        } else {
            $this->context = new Smarty();
        }

        if ($this->compilePath !== null) {
            $this->log("Using compilePath: " . $this->compilePath);
            $this->context->compile_dir = $this->compilePath;
        }

        if ($this->configPath !== null) {
            $this->log("Using configPath: " . $this->configPath);
            $this->context->config_dir = $this->configPath;
        }

        if ($this->forceCompile !== null) {
            $this->context->force_compile = $this->forceCompile;
        }

        if ($this->leftDelimiter !== null) {
            $this->context->left_delimiter = $this->leftDelimiter;
        }

        if ($this->rightDelimiter !== null) {
            $this->context->right_delimiter = $this->rightDelimiter;
        }

        if ($this->templatePath !== null) {
            $this->log("Using templatePath: " . $this->templatePath);
            $this->context->template_dir = $this->templatePath;
        }

        $smartyCompilePath = new PhingFile($this->context->compile_dir);
        if (!$smartyCompilePath->exists()) {
            $this->log(
                "Compile directory does not exist, creating: " . $smartyCompilePath->getPath(),
                Project::MSG_VERBOSE
            );
            if (!$smartyCompilePath->mkdirs()) {
                throw new BuildException("Smarty needs a place to compile templates; specify a 'compilePath' or create " . $this->context->compile_dir);
            }
        }

        // Make sure the output directory exists, if it doesn't
        // then create it.
        $file = new PhingFile($this->outputDirectory);
        if (!$file->exists()) {
            $this->log("Output directory does not exist, creating: " . $file->getAbsolutePath());
            $file->mkdirs();
        }

        $path = $this->outputDirectory . DIRECTORY_SEPARATOR . $this->outputFile;
        $this->log("Generating to file " . $path);

        $writer = new FileWriter($path);

        // The generator and the output path should
        // be placed in the init context here and
        // not in the generator class itself.
        $c = $this->initControlContext();

        // Set any variables that need to always
        // be loaded
        $this->populateInitialContext($c);

        // Feed all the options into the initial
        // control context so they are available
        // in the control/worker templates.
        if ($this->contextProperties !== null) {
            foreach ($this->contextProperties->keys() as $property) {
                $value = $this->contextProperties->getProperty($property);

                // Special exception (from Texen)
                // for properties ending in file.contents:
                // in that case we dump the contents of the file
                // as the "value" for the Property.
                if (StringHelper::endsWith("file.contents", $property)) {
                    // pull in contents of file specified

                    $property = substr($property, 0, strpos($property, "file.contents") - 1);

                    // reset value, and then
                    // read in the contents of the file into that var
                    $value = "";
                    $f = new PhingFile($this->project->resolveFile($value)->getCanonicalPath());
                    if ($f->exists()) {
                        try {
                            $br = new BufferedReader(new FileReader($f));
                            $value = $br->read();
                        } catch (Exception $e) {
                            throw $e;
                        }
                    }
                } // if ends with file.contents

                if (StringHelper::isBoolean($value)) {
                    $value = StringHelper::booleanValue($value);
                }

                $c->assign($property, $value);
            } // foreach property
        } // if contextProperties !== null

        try {
            //$c->display($this->controlTemplate);
            $writer->write($c->fetch($this->controlTemplate));
            $writer->close();
        } catch (IOException $ioe) {
            $writer->close();
            throw new BuildException("Cannot write parsed template.");
        }

        $this->cleanup();
    }
484141
public function main()
    {
        if ($this->name === null) {
            throw new BuildException("The name attribute is required for adhoc task definition.", $this->getLocation());
        }

        $this->execute();

        $classes = $this->getNewClasses();
        if (count($classes) !== 1) {
            throw new BuildException("You must define one (and only one) class for AdhocTypedefTask.");
        }
        $classname = array_shift($classes);

        // instantiate it to make sure it is an instance of ProjectComponent
        $t = new $classname();
        if (!($t instanceof ProjectComponent)) {
            throw new BuildException(
                "The adhoc class you defined must be an instance of phing.ProjectComponent",
                $this->getLocation()
            );
        }

        $this->log("Datatype " . $this->name . " will be handled by class " . $classname, Project::MSG_VERBOSE);
        $this->project->addDataTypeDefinition($this->name, $classname);
    }
154507
public function main()
    {
        if (null === $this->getRepository()) {
            throw new BuildException('"repository" is required parameter');
        }

        $client = $this->getGitClient(false, $this->getRepository());
        $command = $client->getCommand('push');
        $command
            ->setOption('tags', $this->isTags())
            ->setOption('mirror', $this->isMirror())
            ->setOption('delete', $this->isDelete())
            ->setOption('q', $this->isQuiet())
            ->setOption('force', $this->isForce());

        // set operation target
        if ($this->isAllRemotes()) { // --all
            $command->setOption('all', true);
            $this->log('git-push: push to all refs', Project::MSG_INFO);
        } elseif ($this->isMirror()) { // <repository> [<refspec>]
            $command->setOption('mirror', true);
            $this->log('git-push: mirror all refs', Project::MSG_INFO);
        } elseif ($this->getDestination()) { // <repository> [<refspec>]
            $command->addArgument($this->getDestination());
            if ($this->getRefspec()) {
                $command->addArgument($this->getRefspec());
            }
            $this->log(
                sprintf(
                    'git-push: pushing to %s %s',
                    $this->getDestination(),
                    $this->getRefspec()
                ),
                Project::MSG_INFO
            );
        } else {
            throw new BuildException('At least one destination must be provided');
        }

        $this->log('git-push command: ' . $command->createCommandString(), Project::MSG_INFO);

        try {
            $output = $command->execute();
        } catch (Exception $e) {
            throw new BuildException('Task execution failed.', $e);
        }

        $this->log('git-push: complete', Project::MSG_INFO);
        if ($this->isDelete()) {
            $this->log('git-push: branch delete requested', Project::MSG_INFO);
        }
        $this->log('git-push output: ' . trim($output), Project::MSG_INFO);
    }