Пример #1
0
 /**
  * Update the current remote server with the array of files provided.
  *
  * @param array $files 2-dimensional array with 2 indices: 'upload' and 'delete'
  *                     Each of these contains an array of filenames and paths (relative to repository root)
  */
 public function push($files, $localRevision = null)
 {
     if (empty($localRevision)) {
         // We will write this in the server
         $localRevision = $this->currentRevision();
     }
     $initialBranch = $this->currentBranch();
     // If revision is not HEAD, the current one, it means this is a rollback.
     // So, we have to revert the files the the state they were in that revision.
     if ($this->revision != 'HEAD') {
         $this->cli->out('   Rolling back working copy');
         // BUG: This does NOT work correctly for submodules & subsubmodules (and leaves them in an incorrect state)
         //      It technically should do a submodule update in the parent, not a checkout inside the submodule
         $this->git->command('checkout ' . $this->revision, $this->repo);
     }
     $filesToDelete = $files['delete'];
     // Add deleted directories to the list of files to delete. Git does not handle this.
     $dirsToDelete = [];
     if (count($filesToDelete) > 0) {
         $dirsToDelete = $this->hasDeletedDirectories($filesToDelete);
     }
     $filesToUpload = $files['upload'];
     unset($files);
     // No longer needed
     // Upload Files
     if (count($filesToUpload) > 0) {
         foreach ($filesToUpload as $fileNo => $file) {
             if ($this->currentSubmoduleName) {
                 $file = $this->currentSubmoduleName . '/' . $file;
             }
             // Make sure the folder exists in the FTP server.
             $dir = explode('/', dirname($file));
             $path = '';
             $ret = true;
             // Skip mkdir if dir is basedir
             if ($dir[0] !== '.') {
                 // Loop through each folder in the path /a/b/c/d.txt to ensure that it exists
                 // @TODO Can be improved by using: $filesystem->write('path/to/file.txt', 'contents');
                 for ($i = 0, $count = count($dir); $i < $count; ++$i) {
                     $path .= $dir[$i] . '/';
                     if (!isset($pathsThatExist[$path])) {
                         if (!$this->connection->has($path)) {
                             $this->connection->createDir($path);
                             $this->cli->out(" + Created directory '{$path}'.");
                             $pathsThatExist[$path] = true;
                         } else {
                             $pathsThatExist[$path] = true;
                         }
                     }
                 }
             }
             $filePath = $this->repo . '/' . ($this->currentSubmoduleName ? str_replace($this->currentSubmoduleName . '/', '', $file) : $file);
             $data = @file_get_contents($filePath);
             // It can happen the path is wrong, especially with included files.
             if ($data === false) {
                 $this->cli->error(' ! File not found - please check path: ' . $filePath);
                 continue;
             }
             $remoteFile = $file;
             $uploaded = $this->connection->put($remoteFile, $data);
             if (!$uploaded) {
                 $this->cli->error(" ! Failed to upload {$file}.");
             } else {
                 $this->deploymentSize += filesize($this->repo . '/' . ($this->currentSubmoduleName ? str_replace($this->currentSubmoduleName . '/', '', $file) : $file));
             }
             $numberOfFilesToUpdate = count($filesToUpload);
             $fileNo = str_pad(++$fileNo, strlen($numberOfFilesToUpdate), ' ', STR_PAD_LEFT);
             $this->cli->lightGreen(" ^ {$fileNo} of {$numberOfFilesToUpdate} <white>{$file}");
         }
     }
     // Delete files
     if (count($filesToDelete) > 0) {
         foreach ($filesToDelete as $fileNo => $file) {
             if ($this->currentSubmoduleName) {
                 $file = $this->currentSubmoduleName . '/' . $file;
             }
             $numberOfFilesToDelete = count($filesToDelete);
             $fileNo = str_pad(++$fileNo, strlen($numberOfFilesToDelete), ' ', STR_PAD_LEFT);
             if ($this->connection->has($file)) {
                 $this->connection->delete($file);
                 $this->cli->out("<red> × {$fileNo} of {$numberOfFilesToDelete} <white>{$file}");
             } else {
                 $this->cli->out("<red> ! {$fileNo} of {$numberOfFilesToDelete} <white>{$file} not found");
             }
         }
     }
     // Delete Directories
     if (count($dirsToDelete) > 0) {
         foreach ($dirsToDelete as $dirNo => $dir) {
             if ($this->currentSubmoduleName) {
                 $dir = $this->currentSubmoduleName . '/' . $dir;
             }
             $numberOfdirsToDelete = count($dirsToDelete);
             $dirNo = str_pad(++$dirNo, strlen($numberOfdirsToDelete), ' ', STR_PAD_LEFT);
             if ($this->connection->has($dir)) {
                 $this->connection->deleteDir($dir);
                 $this->cli->out("<red> × {$dirNo} of {$numberOfdirsToDelete} <white>{$dir}");
             } else {
                 $this->cli->out("<red> ! {$dirNo} of {$numberOfdirsToDelete} <white>{$dir} not found");
             }
         }
     }
     if (count($filesToUpload) > 0 or count($filesToDelete) > 0) {
         $this->setRevision($localRevision);
     } else {
         $this->cli->gray()->out('   No files to upload or delete.');
     }
     // If $this->revision is not HEAD, it means the rollback command was provided
     // The working copy was rolled back earlier to run the deployment, and we
     // now want to return the working copy back to its original state.
     if ($this->revision != 'HEAD') {
         $this->git->command('checkout ' . ($initialBranch ?: 'master'));
     }
     $this->log('[SHA: ' . $localRevision . '] Deployment to server: "' . $this->currentlyDeploying . '" from branch "' . $initialBranch . '". ' . count($filesToUpload) . ' files uploaded; ' . count($filesToDelete) . ' files deleted.');
 }