/** * @throws \Exception */ public function run() { if (!$this->command instanceof ProvisionCommand) { throw new \Exception("The ConfigDefaults task can only be run by the Provision command."); } $fs = Util::getFilesystem(); $config_files = SyncManager::getRules(SyncManager::SYNC_FILE); $config_dirs = SyncManager::getRules(SyncManager::SYNC_DIR); $config_sources = array_merge(array_column($config_files, 'source'), array_column($config_dirs, 'source')); if ($fs->exists($config_sources)) { return; } $config_sources_dirs = []; foreach ($config_sources as $config_source) { $config_source_dir = dirname($config_source); while ($config_source_dir != '/vagrant' && !in_array($config_source_dir, $config_sources_dirs)) { $config_sources_dirs[] = $config_source_dir; $config_source_dir = dirname($config_source_dir); } } $fs->mkdir($config_sources_dirs, 0777, 'vagrant'); foreach ($config_files as $file) { if (empty($file['default'])) { continue; } $target_file = $file['source']; $origin_file = $file['default']; if (!file_exists($target_file)) { $this->output->writeInfo("Writing default config file '{$target_file}'"); $fs->copy($origin_file, $target_file, true, 'vagrant'); } } foreach ($config_dirs as $dir) { if (empty($dir['default'])) { continue; } $source_dir = $dir['default']; $target_dir = $dir['source']; if (file_exists($target_dir)) { continue; } $this->output->writeInfo("Writing default config dir '{$target_dir}'"); $fs->mkdir($target_dir, 0777, 'vagrant'); $finder = new Finder(); foreach ($finder->files()->in($source_dir)->ignoreDotFiles(false)->depth('== 0') as $origin_dir_file) { $origin_dir_filename = $origin_dir_file->getFilename(); $target_dir_filepath = $target_dir . '/' . $origin_dir_filename; $origin_dir_filepath = $source_dir . '/' . $origin_dir_filename; $fs->copy($origin_dir_filepath, $target_dir_filepath, true, 'vagrant'); } } }
/** * Syncs directories files between the host and guest using bi-directional sync algorithm */ protected function syncDirs() { $fs = Util::getFilesystem(); $sync_status = []; if (file_exists(self::SYNC_STATUS_FILE)) { $sync_status = json_decode(file_get_contents(self::SYNC_STATUS_FILE), true); } $sync_status_new = []; $config_dirs = SyncManager::getRules(SyncManager::SYNC_DIR); foreach ($config_dirs as $dir) { if (empty($dir['path'])) { continue; } $source_dir = $dir['source']; $source_dir_owner = 'vagrant'; $source_dir_group = 'vagrant'; $target_dir = $dir['path']; $target_dir_owner = !empty($dir['owner']) ? $dir['owner'] : null; $target_dir_group = !empty($dir['group']) ? $dir['group'] : null; if ($source_dir == $target_dir) { continue; } $dir_sync_status = ['old' => [], 'new' => []]; if (isset($sync_status[$target_dir])) { $dir_sync_status['old'] = $sync_status[$target_dir]; } $finder = new Finder(); foreach ($finder->files()->in($source_dir)->ignoreDotFiles(false)->depth('== 0') as $source_dir_file) { $source_dir_filename = $source_dir_file->getFilename(); $source_dir_filepath = $source_dir . '/' . $source_dir_filename; $target_dir_filepath = $target_dir . '/' . $source_dir_filename; // Sync file changes if (file_exists($target_dir_filepath)) { $dir_sync_status['new'][] = $source_dir_filename; if (md5_file($source_dir_filepath) === md5_file($target_dir_filepath)) { continue; } $source_dir_filetime = filemtime($source_dir_filepath); $target_dir_filetime = filemtime($target_dir_filepath); if ($source_dir_filetime >= $target_dir_filetime) { $copy_from = $source_dir_filepath; $copy_to = $target_dir_filepath; $copy_owner = $target_dir_owner; $copy_group = $target_dir_group; } else { $copy_from = $target_dir_filepath; $copy_to = $source_dir_filepath; $copy_owner = $source_dir_owner; $copy_group = $source_dir_group; } $this->output->writeInfo("Syncing config file '{$source_dir_filepath}' " . ($copy_from == $source_dir_filepath ? "->" : "<-") . " '{$target_dir_filepath}'"); $fs->copy($copy_from, $copy_to, true, $copy_owner, $copy_group); } else { if (in_array($source_dir_filename, $dir_sync_status['old'])) { $this->output->writeInfo("Removing config file '{$source_dir_filepath}'"); $fs->remove($source_dir_filepath); } else { $dir_sync_status['new'][] = $source_dir_filename; $this->output->writeInfo("Copying config file '{$source_dir_filepath}' -> '{$target_dir_filepath}'"); $fs->copy($source_dir_filepath, $target_dir_filepath, true, $target_dir_owner, $target_dir_group); } } } $finder = new Finder(); foreach ($finder->files()->in($target_dir)->ignoreDotFiles(false)->depth('== 0') as $target_dir_file) { $target_dir_filename = $target_dir_file->getFilename(); $source_dir_filepath = $source_dir . '/' . $target_dir_filename; $target_dir_filepath = $target_dir . '/' . $target_dir_filename; if (in_array($target_dir_filename, $dir_sync_status['new'])) { continue; } // Delete file from target dir if (in_array($target_dir_filename, $dir_sync_status['old'])) { $this->output->writeInfo("Removing config file '{$target_dir_filepath}'"); $fs->remove($target_dir_filepath); } else { $this->output->writeInfo("Copying config file '{$source_dir_filepath}' <- '{$target_dir_filepath}'"); $fs->copy($target_dir_filepath, $source_dir_filepath, true, $source_dir_owner, $source_dir_group); $dir_sync_status['new'][] = $target_dir_filename; } } $sync_status_new[$target_dir] = $dir_sync_status['new']; } // Write status file $this->output->writeDebug("Writing config directories sync status file"); $fs->write(self::SYNC_STATUS_FILE, json_encode($sync_status_new), 'vagrant'); }