Modules may claim "tokens" for themselves. A token, in that sense, can be
any integer or string. If modules claim the same token, a conflict is
raised:
php
use Puli\Manager\Conflict\ModuleConflictDetector;
$detector = new ModuleConflictDetector();
$detector->claim('/app/config', 'module1');
$detector->claim('/app/views', 'module2');
$conflicts = $detector->detectConflicts(array('/app/config', '/app/views'));
=> array()
$detector->claim('/app/config', 'module2');
$conflicts = $detector->detectConflicts(array('/app/config', '/app/views'));
=> array(ModuleConflict)
You can resolve conflicts by passing an {@link OverrideGraph} to the
detector. The override graph has module names as nodes. When the conflict
graph contains an edge from module A to module B, then module A is
considered to be overridden by module B. Claims for the same resources will
not result in conflicts for these modules:
php
use Puli\Manager\Conflict\OverrideGraph;
use Puli\Manager\Conflict\ModuleConflictDetector;
$graph = new OverrideGraph();
$graph->addModuleName('module1');
$graph->addModuleName('module2');
module1 is overridden by module2
$graph->addEdge('module1', 'module2');
$detector = new ModuleConflictDetector($graph);
$detector->claim('/app/config', 'module1');
$detector->claim('/app/config', 'module2');
The conflict has been resolved
$conflict s= $detector->detectConflict(array('/app/config'));
=> array()
/** * {@inheritdoc} */ public function execute() { if (!$this->repositoryPaths) { // Check all paths if none are passed $this->repositoryPaths = $this->conflicts->getRepositoryPaths(); } // Mark all as resolved foreach ($this->repositoryPaths as $repositoryPath) { if ($this->conflicts->has($repositoryPath)) { $conflict = $this->conflicts->get($repositoryPath); $this->conflicts->remove($repositoryPath); $this->removedConflicts[$repositoryPath] = $conflict->getMappings(); $conflict->resolve(); } } $moduleConflicts = $this->conflictDetector->detectConflicts($this->repositoryPaths); $this->deduplicateModuleConflicts($moduleConflicts); foreach ($moduleConflicts as $moduleConflict) { $repositoryPath = $moduleConflict->getConflictingToken(); $conflict = new PathConflict($repositoryPath); foreach ($moduleConflict->getModuleNames() as $moduleName) { $conflict->addMapping($this->mappingsByResource->get($repositoryPath, $moduleName)); } $this->conflicts->add($conflict); $this->addedConflicts[] = $repositoryPath; } }
/** * {@inheritdoc} */ public function rollback() { if (!$this->mapping->isLoaded()) { return; } $moduleName = $this->containingModule->getName(); $this->mappings->remove($this->mapping->getRepositoryPath(), $moduleName); foreach ($this->mapping->listRepositoryPaths() as $repositoryPath) { $this->mappingsByResource->remove($repositoryPath, $moduleName); $this->conflictDetector->release($repositoryPath, $moduleName); } // Unload after iterating, otherwise the paths are gone $this->mapping->unload(); }
/** * {@inheritdoc} */ public function rollback() { if ($this->mapping->isLoaded() || !$this->containingModule) { return; } $this->mapping->load($this->containingModule, $this->modules); $moduleName = $this->containingModule->getName(); foreach ($this->mapping->listRepositoryPaths() as $repositoryPath) { $this->mappings->add($this->mapping); $this->conflictDetector->claim($repositoryPath, $moduleName); } // Restore conflicts foreach ($this->conflicts as $repositoryPath => $conflict) { $conflict->addMappings($this->conflictingMappings[$repositoryPath]); } }