Switch the current release symlink to the previous release.

@param string $releasesDir
Path to the folder containing all releases.
@param string $currentSymlink
Path to the current release symlink.
544023
public function digipolisSwitchPrevious($releasesDir, $currentSymlink)
    {
        $finder = new Finder();
        // Get all releases.
        $releases = iterator_to_array(
            $finder
                ->directories()
                ->in($releasesDir)
                ->sortByName()
                ->depth(0)
                ->getIterator()
        );
        // Last element is the current release.
        array_pop($releases);
        if ($releases) {
            // Normalize the paths.
            $currentDir = readlink($currentSymlink);
            $releasesDir = realpath($releasesDir);
            // Get the right folder within the release dir to symlink.
            $relativeRootDir = substr($currentDir, strlen($releasesDir . '/'));
            $parts = explode('/', $relativeRootDir);
            array_shift($parts);
            $relativeWebDir = implode('/', $parts);
            $previous = end($releases)->getRealPath() . '/' . $relativeWebDir;
            return $this->taskExec('ln -s -T -f ' . $previous . ' ' . $currentSymlink)
                ->run();
        }
    }
309175
public static function link($target, $link)
  {
    if (! windows_os()) {
      return symlink($target, $link);
    }

    $mode = is_dir($target) ? 'J' : 'H';

    exec("mklink /{$mode} \"{$link}\" \"{$target}\"");
  }
1366328
protected function setReleaseVersion()
    {
        try {
            $currentVersion = Context::get('version-persister')->getCurrentVersion();
        } catch (\Exception $e) {
            $currentVersion = Context::get('version-generator')->getInitialVersion();
        }

        $this->releaseVersion = Context::get('version-generator')->generateNextVersion($currentVersion);
    }
588666
protected function symlinkLegacyExtensionFiles(string $legacyExtensionPath, OutputInterface $output): void
    {
        /** @var \DirectoryIterator[] $directories */
        $directories = [];

        $path = $legacyExtensionPath . '/root_' . $this->environment . '/';
        if ($this->fileSystem->exists($path) && is_dir($path)) {
            $directories[] = new DirectoryIterator($path);
        }

        $path = $legacyExtensionPath . '/root/';
        if ($this->fileSystem->exists($path) && is_dir($path)) {
            $directories[] = new DirectoryIterator($path);
        }

        foreach ($directories as $directory) {
            foreach ($directory as $item) {
                if ($item->isDot() || $item->isLink()) {
                    continue;
                }

                if ($item->isDir() && in_array($item->getBasename(), self::$legacyDistFolders, true)) {
                    if (in_array($item->getBasename(), self::$blacklistedItems, true)) {
                        continue;
                    }

                    foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($item->getPathname())) as $subItem) {
                        /** @var \SplFileInfo $subItem */
                        if ($subItem->isFile() && !$subItem->isLink()) {
                            if (in_array($subItem->getBasename(), self::$blacklistedItems, true)) {
                                continue;
                            }

                            // Allow filename to have .patched at the end of string (dehctap. in reverse file name)
                            // to work around eZ legacy autoload generator warning about duplicate class names
                            $fileName = $subItem->getBasename();
                            if (mb_strpos(strrev($fileName), 'dehctap.') === 0) {
                                $fileName = str_replace('.patched', '', $fileName);
                            }

                            $filePath = $this->fileSystem->makePathRelative(
                                realpath($subItem->getPath()),
                                $directory->getPath()
                            ) . $fileName;

                            $filePath = $this->getContainer()->getParameter('ezpublish_legacy.root_dir') . '/' . $filePath;

                            if ($this->fileSystem->exists($filePath) && is_file($filePath) && !is_link($filePath)) {
                                // If the destination is a real file, we'll just overwrite it, with backup
                                // but only if it differs from the original
                                if (md5(file_get_contents($subItem->getPathname())) === md5(file_get_contents($filePath))) {
                                    continue;
                                }

                                $this->fileSystem->copy($filePath, $filePath . '.backup.' . date('Y-m-d-H-i-s'), true);
                                $this->fileSystem->copy($subItem->getPathname(), $filePath, true);
                            } elseif (!$this->fileSystem->exists($filePath) || is_link($filePath)) {
                                $this->verifyAndSymlinkFile(
                                    $subItem->getPathname(),
                                    $filePath,
                                    $output
                                );
                            }
                        }
                    }
                } elseif ($item->isDir() || $item->isFile()) {
                    if (in_array($item->getBasename(), self::$blacklistedItems, true)) {
                        continue;
                    }

                    $destination = $this->getContainer()->getParameter('ezpublish_legacy.root_dir') . '/' . $item->getBasename();

                    if ($item->isDir()) {
                        $this->verifyAndSymlinkDirectory(
                            $item->getPathname(),
                            $destination,
                            $output
                        );
                    } else {
                        $this->verifyAndSymlinkFile(
                            $item->getPathname(),
                            $destination,
                            $output
                        );
                    }
                }
            }
        }
    }
697060
public static function symlink($path, $link_path, $is_file = true, $area = null)
	{
		$path      = rtrim(static::instance($area)->get_path($path), '\\/');
		$link_path = rtrim(static::instance($area)->get_path($link_path), '\\/');

		if ($is_file and ! is_file($path))
		{
			throw new \InvalidPathException('Cannot symlink: given file: "'.$path.'" does not exist.');
		}
		elseif ( ! $is_file and ! is_dir($path))
		{
			throw new \InvalidPathException('Cannot symlink: given directory: "'.$path.'" does not exist.');
		}
		elseif (file_exists($link_path))
		{
			throw new \FileAccessException('Cannot symlink: link: "'.$link_path.'" already exists.');
		}

		return symlink($path, $link_path);
	}
536002
public function handle($symlink)
    {
        $symlink = $this->filesystem->getAdapter()->applyPathPrefix($symlink);

        if (!\is_link($symlink)) {
            return false;
        }

        if (Console::isWindows() && \is_dir($symlink)) {
            return \rmdir($symlink);
        } else {
            return \unlink($symlink);
        }
    }
850382
public function end(InstallableInterface $bundle, $currentVersion = null, $targetVersion = null)
    {
        $additionalInstaller = $this->getAdditionalInstaller($bundle);

        if ($additionalInstaller) {
            $additionalInstaller->end($currentVersion, $targetVersion);
        }
    }
1143867
protected function deleteVirtualFolder( $currentSite, $target )
    {
        $target = $this->splitFirstPathElement( $target, $virtualFolder );

        if ( !in_array( $virtualFolder, array( self::virtualContentFolderName(), self::virtualMediaFolderName() ) ) )
        {
            return false; // @as self::FAILED_NOT_FOUND;
        }

        if ( !$target )
        {
            // We have reached the end of the path
            // We do not allow 'delete' operations for the virtual folder.
            return false; // @as self::FAILED_FORBIDDEN;
        }

        if ( $virtualFolder === self::virtualContentFolderName() or
             $virtualFolder === self::virtualMediaFolderName() )
        {
            return $this->deleteContent( $currentSite, $virtualFolder, $target );
        }

        return false; // @as self::FAILED_FORBIDDEN;
    }
487192
protected function createSymbolicLink()
    {
        $this->displayMsgInCli(' > Create symbolic link ... ');

        $alreadyCreated = file_exists($this->targetSrcPath);

        //If symlink already exist and it's a reinstall mode
        if ($alreadyCreated && $this->forceReinstall === true) {
            $this->displayMsgInCli('[Force Reinstall: Remove symlink] ');
            $alreadyCreated = false;

            //Error with remove symlink
            if (!unlink($this->targetSrcPath)) {
                $this->displayMsgNLInCli('Symbolic link remove fail.', 'red', 'bold');
                
                throw new Exception(
                    'Reinstall fail. Symlink remove error',
                    $this::ERR_REINSTALL_FAIL_UNLINK
                );
            }
        }

        //If module already exist in "modules" directory
        if ($alreadyCreated) {
            $this->displayMsgNLInCli(
                'Not created. Module already exist in \'modules\' directory.',
                'yellow',
                'bold'
            );
            return;
        }

        //If the creation of the symbolic link has failed.
        if (!symlink($this->sourceSrcPath, $this->targetSrcPath)) {
            $this->displayMsgNLInCli('Symbolic link creation fail.', 'red', 'bold');
            
            throw new Exception(
                'Symbolic link creation fail.',
                $this::ERR_INSTALL_FAIL_SYMLINK
            );
        }

        $this->displayMsgNLInCli('Done', 'green', 'bold');
    }
258721
public function onDeployOrRollbackReleaseLinkRelease(DeployReleaseEvent $event, $eventName, EventDispatcherInterface $eventDispatcher)
    {
        $release = $event->getRelease();
        $host = $release->getWorkspace()->getHost();
        $connection = $this->ensureConnection($host);

        $releasePath = $host->getPath().'/'.$host->getStage();

        $context = array('linkTarget' => $releasePath, 'releaseVersion' => $release->getVersion(), 'event.task.action' => TaskInterface::ACTION_IN_PROGRESS);
        $eventDispatcher->dispatch(AccompliEvents::LOG, new LogEvent(LogLevel::NOTICE, 'Linking "{linkTarget}" to release "{releaseVersion}".', $eventName, $this, $context));

        if ($connection->isLink($releasePath) === false || $connection->readLink($releasePath) !== $release->getPath()) {
            if ($connection->isLink($releasePath)) {
                $connection->delete($releasePath, false);
            }

            if ($connection->link($release->getPath(), $releasePath)) {
                $context['event.task.action'] = TaskInterface::ACTION_COMPLETED;
                $context['output.resetLine'] = true;

                $eventDispatcher->dispatch(AccompliEvents::LOG, new LogEvent(LogLevel::NOTICE, 'Linked "{linkTarget}" to release "{releaseVersion}".', $eventName, $this, $context));
            } else {
                $context['event.task.action'] = TaskInterface::ACTION_FAILED;
                $context['output.resetLine'] = true;

                $eventDispatcher->dispatch(AccompliEvents::LOG, new LogEvent(LogLevel::NOTICE, 'Linking "{linkTarget}" to release "{releaseVersion}" failed.', $eventName, $this, $context));

                throw new TaskRuntimeException(sprintf('Linking "%s" to release "%s" failed.', $context['linkTarget'], $context['releaseVersion']), $this);
            }
        } else {
            $context['event.task.action'] = TaskInterface::ACTION_COMPLETED;
            $context['output.resetLine'] = true;

            $eventDispatcher->dispatch(AccompliEvents::LOG, new LogEvent(LogLevel::NOTICE, 'Link "{linkTarget}" to release "{releaseVersion}" already exists.', $eventName, $this, $context));
        }
    }
614917
protected function verifyAndSymlinkDirectory(string $source, string $destination, OutputInterface $output): void
    {
        if ($this->fileSystem->exists($destination) && !is_link($destination)) {
            $output->writeln('<comment>' . basename($destination) . '</comment> already exists in <comment>' . dirname($destination) . '/</comment> and is not a symlink. Skipping...');

            return;
        }

        if ($this->forceSymlinks && is_link($destination)) {
            $this->fileSystem->remove($destination);
        }

        if ($this->fileSystem->exists($destination)) {
            $output->writeln('Skipped creating the symlink for <comment>' . basename($destination) . '</comment> in <comment>' . dirname($destination) . '/</comment>. Symlink already exists!');

            return;
        }

        $this->fileSystem->symlink(
            $this->fileSystem->makePathRelative(
                $source,
                realpath(dirname($destination))
            ),
            $destination
        );
    }
150887
private function absoluteSymlinkWithFallback($originDir, $targetDir)
    {
        try {
            $this->symlink($originDir, $targetDir);
            $method = self::METHOD_ABSOLUTE_SYMLINK;
        } catch (IOException $e) {
            // fall back to copy
            $method = $this->hardCopy($originDir, $targetDir);
        }

        return $method;
    }
984066
def symlink_remove(link):
    
    # https://stackoverflow.com/q/26554135/6400719
    if os.path.isdir(path2str(link)) and is_windows:
        # this should only be on Py2.7 and windows
        os.rmdir(path2str(link))
    else:
        os.unlink(path2str(link))
109399
public function getCurrentRelease()
    {
        $current = Arr::get($this->getValidReleases(), 0);
        $current = $this->sanitizeRelease($current);

        return $this->nextRelease ?: $current;
    }
404535
public function moveFolder($currentFolder, $newFolder)
    {
        if ($newFolder == $currentFolder) {
            $this->errors[] = 'Please select another folder to move this folder into.';

            return false;
        }

        if (starts_with($newFolder, $currentFolder)) {
            $this->errors[] = 'You can not move this folder inside of itself.';

            return false;
        }

        return $this->disk->getDriver()->rename($currentFolder, $newFolder);
    }
850361
private function symlink(string $originDir, string $targetDir, bool $relative = false)
    {
        if ($relative) {
            $this->filesystem->mkdir(\dirname($targetDir));
            $originDir = $this->filesystem->makePathRelative($originDir, realpath(\dirname($targetDir)));
        }
        $this->filesystem->symlink($originDir, $targetDir);
        if (!file_exists($targetDir)) {
            throw new IOException(sprintf('Symbolic link "%s" was created but appears to be broken.', $targetDir), 0, null, $targetDir);
        }
    }
980865
public function processSymlink(Symlink $symlink): bool
    {
        if ($symlink->isForceCreate() && $this->isToUnlink($symlink->getLink())) {
            try {
                if (\is_dir($symlink->getLink())) {
                    $result = $this->filesystem->removeDirectory($symlink->getLink());
                } else {
                    $result = $this->filesystem->remove($symlink->getLink());
                }
                if (!$result) {
                    throw new RuntimeException('Unknown error');
                }
            } catch (\Exception $exception) {
                throw new RuntimeException(sprintf(
                    'Cant unlink %s: %s',
                    $symlink->getLink(),
                    $exception->getMessage()
                ));
            }
        }

        if ($this->isToUnlink($symlink->getLink())) {
            throw new LinkDirectoryError('Link ' . $symlink->getLink() . ' already exists');
        }

        if ($symlink->isAbsolutePath()) {
            return @symlink($symlink->getTarget(), $symlink->getLink());
        }
        return $this->filesystem->relativeSymlink($symlink->getTarget(), $symlink->getLink());
    }