/** * Synchronize remote and local. * @return void */ public function deploy() { $this->logger->log("Connecting to server"); $this->server->connect(); $runBefore = [NULL, NULL]; foreach ($this->runBefore as $job) { $runBefore[is_string($job) && preg_match('#^local:#', $job)][] = $job; } if ($runBefore[1]) { $this->logger->log("\nLocal-jobs:"); $this->runJobs($runBefore[1]); $this->logger->log(''); } $remoteFiles = $this->loadDeploymentFile(); if (is_array($remoteFiles)) { $this->logger->log("Loaded remote {$this->deploymentFile} file"); } else { $this->logger->log("Remote {$this->deploymentFile} file not found"); $remoteFiles = []; } $this->logger->log("Scanning files in {$this->local}"); $localFiles = $this->collectFiles(); unset($localFiles["/{$this->deploymentFile}"], $remoteFiles["/{$this->deploymentFile}"]); $toDelete = $this->allowDelete ? array_keys(array_diff_key($remoteFiles, $localFiles)) : []; $toUpload = array_keys(array_diff_assoc($localFiles, $remoteFiles)); if ($localFiles !== $remoteFiles) { // ignores allowDelete $deploymentFile = $this->writeDeploymentFile($localFiles); $toUpload[] = "/{$this->deploymentFile}"; // must be last } if (!$toUpload && !$toDelete) { $this->logger->log('Already synchronized.', 'lime'); return; } elseif ($this->testMode) { $this->logger->log("\nUploading:\n" . implode("\n", $toUpload), 'green', FALSE); $this->logger->log("\nDeleting:\n" . implode("\n", $toDelete), 'maroon', FALSE); if (isset($deploymentFile)) { unlink($deploymentFile); } return; } $this->logger->log("Creating remote file {$this->deploymentFile}.running"); $root = $this->server->getDir(); $runningFile = "{$root}/{$this->deploymentFile}.running"; $this->server->createDir(str_replace('\\', '/', dirname($runningFile))); $this->server->writeFile(tempnam($this->tempDir, 'deploy'), $runningFile); if ($runBefore[0]) { $this->logger->log("\nBefore-jobs:"); $this->runJobs($runBefore[0]); } if ($toUpload) { $this->logger->log("\nUploading:"); if ($this->zip) { $size = $this->uploadFilesZipped($toUpload); $unzipScript = tempnam($this->tempDir, 'unzip'); file_put_contents($unzipScript, str_replace('%ZIP_PATH%', str_repeat('../', $this->getDirLevel($this->zip['documentRoot'])) . '.deployment.zip', file_get_contents(__DIR__ . '/unzip.php.bin'))); $this->server->writeFile($unzipScript, ($unzipRemote = $this->zip['documentRoot'] . '/unzip.php') . self::TEMPORARY_SUFFIX); $this->server->renameFile($unzipRemote . self::TEMPORARY_SUFFIX, $unzipRemote); $this->logger->log('unzipping on remote: ' . $this->zip['serverUrl'] . 'unzip.php'); $f = fopen($this->zip['serverUrl'] . 'unzip.php', 'r'); while (($line = fgets($f)) !== FALSE) { $percent = $line * 100 / $size; printf("Unzipping [%3d%%]\r", $percent); } fclose($f); if (!empty($this->zip['deleteZipAfterDeploy'])) { $this->logger->log("\nDeleting zip archive"); $this->server->removeFile('.deployment.zip'); } } else { $this->uploadFiles($toUpload); } unlink($deploymentFile); } if ($toDelete) { $this->logger->log("\nDeleting:"); $this->deleteFiles($toDelete); } foreach ((array) $this->toPurge as $path) { $this->logger->log("\nCleaning {$path}"); $this->server->purge($root . '/' . $path, function ($file) use($root) { static $counter; $file = substr($file, strlen($root)); $file = preg_match('#/(.{1,60})$#', $file, $m) ? $m[1] : substr(basename($file), 0, 60); echo str_pad($file . ' ' . str_repeat('.', $counter++ % 30 + 60 - strlen($file)), 90), "\r"; }); echo str_repeat(' ', 91) . "\r"; } if ($this->runAfter) { $this->logger->log("\nAfter-jobs:"); $this->runJobs($this->runAfter); } $this->logger->log("\nDeleting remote file {$this->deploymentFile}.running"); $this->server->removeFile($runningFile); }