Platformsh\Cli\Local\LocalBuild::buildApp PHP Method

buildApp() protected method

protected buildApp ( LocalApplication $app, string $sourceDir, string $destination = null ) : boolean
$app LocalApplication
$sourceDir string
$destination string
return boolean
    protected function buildApp($app, $sourceDir, $destination = null)
    {
        $verbose = $this->output->isVerbose();
        $destination = $destination ?: $sourceDir . '/' . $this->config->get('local.web_root');
        $appRoot = $app->getRoot();
        $appConfig = $app->getConfig();
        $multiApp = $appRoot != $sourceDir;
        $appId = $app->getId();
        $toolstack = $app->getToolstack();
        if (!$toolstack) {
            $this->output->writeln("Toolstack not found for application <error>{$appId}</error>");
            return false;
        }
        // Find the right build directory.
        $buildName = $multiApp ? str_replace('/', '-', $appId) : 'default';
        $tmpBuildDir = $sourceDir . '/' . $this->config->get('local.build_dir') . '/' . $buildName . '-tmp';
        if (file_exists($tmpBuildDir)) {
            if (!$this->fsHelper->remove($tmpBuildDir)) {
                $this->output->writeln(sprintf('Failed to remove directory <error>%s</error>', $tmpBuildDir));
                return false;
            }
        }
        // If the destination is inside the source directory, ensure it isn't
        // copied or symlinked into the build.
        if (strpos($destination, $sourceDir) === 0) {
            $toolstack->addIgnoredFiles([ltrim(substr($destination, strlen($sourceDir)), '/')]);
        }
        // Warn about a mismatched PHP version.
        if (isset($appConfig['type']) && strpos($appConfig['type'], ':')) {
            list($stack, $version) = explode(':', $appConfig['type'], 2);
            if ($stack === 'php' && version_compare($version, PHP_VERSION, '>')) {
                $this->output->writeln(sprintf('<comment>Warning:</comment> the application <comment>%s</comment> expects PHP %s, but the system version is %s.', $appId, $version, PHP_VERSION));
            }
        }
        $toolstack->setOutput($this->output);
        $buildSettings = $this->settings + ['multiApp' => $multiApp, 'sourceDir' => $sourceDir];
        $toolstack->prepare($tmpBuildDir, $app, $this->config, $buildSettings);
        $archive = false;
        if (empty($this->settings['no-archive']) && empty($this->settings['no-cache'])) {
            $treeId = $this->getTreeId($appRoot);
            if ($treeId) {
                if ($verbose) {
                    $this->output->writeln("Tree ID: {$treeId}");
                }
                $archive = $sourceDir . '/' . $this->config->get('local.archive_dir') . '/' . $treeId . '.tar.gz';
            }
        }
        if ($archive && file_exists($archive)) {
            $message = "Extracting archive for application <info>{$appId}</info>";
            $this->output->writeln($message);
            $this->fsHelper->extractArchive($archive, $tmpBuildDir);
        } else {
            $message = "Building application <info>{$appId}</info>";
            if (isset($appConfig['type'])) {
                $message .= ' (runtime type: ' . $appConfig['type'] . ')';
            }
            $this->output->writeln($message);
            $toolstack->build();
            if ($this->runPostBuildHooks($appConfig, $toolstack->getAppDir()) === false) {
                // The user may not care if build hooks fail, but we should
                // not archive the result.
                $archive = false;
            }
            if ($archive && $toolstack->canArchive()) {
                $this->output->writeln("Saving build archive");
                if (!is_dir(dirname($archive))) {
                    mkdir(dirname($archive));
                }
                $this->fsHelper->archiveDir($tmpBuildDir, $archive);
            }
        }
        // The build is complete. Move the directory.
        $buildDir = substr($tmpBuildDir, 0, strlen($tmpBuildDir) - 4);
        if (file_exists($buildDir)) {
            if (empty($this->settings['no-backup']) && is_dir($buildDir) && !is_link($buildDir)) {
                $previousBuildArchive = dirname($buildDir) . '/' . basename($buildDir) . '-old.tar.gz';
                $this->output->writeln("Backing up previous build to: " . $previousBuildArchive);
                $this->fsHelper->archiveDir($buildDir, $previousBuildArchive);
            }
            if (!$this->fsHelper->remove($buildDir, true)) {
                $this->output->writeln(sprintf('Failed to remove directory <error>%s</error>', $buildDir));
                return false;
            }
        }
        if (!rename($tmpBuildDir, $buildDir)) {
            $this->output->writeln(sprintf('Failed to move temporary build directory into <error>%s</error>', $buildDir));
            return false;
        }
        $toolstack->setBuildDir($buildDir);
        $toolstack->install();
        $this->runPostDeployHooks($appConfig, $buildDir);
        $webRoot = $toolstack->getWebRoot();
        // Symlink the built web root ($webRoot) into www or www/appId.
        if (!is_dir($webRoot)) {
            $this->output->writeln("\nWeb root not found: <error>{$webRoot}</error>\n");
            return false;
        }
        if ($multiApp) {
            $appDir = str_replace('/', '-', $appId);
            if (is_link($destination)) {
                $this->fsHelper->remove($destination);
            }
            $destination .= "/{$appDir}";
        }
        $this->fsHelper->symlink($webRoot, $destination);
        $message = "\nBuild complete for application <info>{$appId}</info>";
        $this->output->writeln($message);
        $this->output->writeln("Web root: <info>{$destination}</info>\n");
        return true;
    }