Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Directory separator and its duplicates #103

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ vendor/
.DS_Store
composer.lock
.phpunit.result.cache

temptestdir
12 changes: 4 additions & 8 deletions src/Composer/Autoload/NamespaceAutoloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace CoenJacobs\Mozart\Composer\Autoload;

use stdClass;

abstract class NamespaceAutoloader implements Autoloader
{
/** @var string */
Expand All @@ -17,7 +19,7 @@ abstract class NamespaceAutoloader implements Autoloader
public $paths = [];

/**
* A package's composer.json config autoload key's value, where $key is `psr-1`|`psr-4`|`classmap`.
* A package's composer.json config autoload key's value, where $key is `psr-0`|`psr-4`|`classmap`.
*
* @param $autoloadConfig
*
Expand All @@ -39,11 +41,5 @@ public function getSearchNamespace()
return $this->namespace;
}

/**
* @return string
*/
public function getNamespacePath()
{
return '';
}
abstract public function getNamespacePath(): string;
}
8 changes: 8 additions & 0 deletions src/Composer/Autoload/Psr0.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
<?php
/**
* @see https://www.php-fig.org/psr/psr-0/
*/

namespace CoenJacobs\Mozart\Composer\Autoload;

class Psr0 extends NamespaceAutoloader
{

public function getNamespacePath(): string
{
return '';
}
}
14 changes: 6 additions & 8 deletions src/Composer/Autoload/Psr4.php
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
<?php
/**
* @see https://www.php-fig.org/psr/psr-4/
*/

namespace CoenJacobs\Mozart\Composer\Autoload;

class Psr4 extends NamespaceAutoloader
{
/**
* @return string
*/
public function getSearchNamespace()

public function getSearchNamespace(): string
{
return trim($this->namespace, '\\');
}

/**
* @return string
*/
public function getNamespacePath()
public function getNamespacePath(): string
{
return str_replace('\\', DIRECTORY_SEPARATOR, $this->namespace);
}
Expand Down
110 changes: 67 additions & 43 deletions src/Mover.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,26 @@
use CoenJacobs\Mozart\Composer\Package;
use League\Flysystem\Adapter\Local;
use League\Flysystem\Filesystem;
use stdClass;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\SplFileInfo;

class Mover
{
/** @var string */
/**
* The only path variable with a leading slash.
*
* @var string
*/
protected $workingDir;

/** @var string */
protected $targetDir;
protected $dep_directory;

/** @var \stdClass */
/** @var string */
protected $classmap_directory;

/** @var stdClass */
protected $config;

/** @var Filesystem */
Expand All @@ -32,10 +40,13 @@ class Mover

public function __construct($workingDir, $config)
{
$this->workingDir = $workingDir;
$this->targetDir = $config->dep_directory;
$this->config = $config;

$this->workingDir = $workingDir;

$this->dep_directory = $this->clean($config->dep_directory);
$this->classmap_directory = $this->clean($config->classmap_directory);

$this->filesystem = new Filesystem(new Local($this->workingDir));
}

Expand All @@ -48,9 +59,9 @@ public function __construct($workingDir, $config)
*/
public function deleteTargetDirs($packages): void
{
$this->filesystem->createDir($this->config->dep_directory);
$this->filesystem->createDir($this->dep_directory);

$this->filesystem->createDir($this->config->classmap_directory);
$this->filesystem->createDir($this->classmap_directory);

foreach ($packages as $package) {
$this->deleteDepTargetDirs($package);
Expand All @@ -74,13 +85,12 @@ private function deleteDepTargetDirs($package): void
switch ($autoloaderType) {
case Psr0::class:
case Psr4::class:
$outputDir = $this->config->dep_directory . $packageAutoloader->namespace;
$outputDir = str_replace('\\', DIRECTORY_SEPARATOR, $outputDir);
$outputDir = $this->dep_directory . DIRECTORY_SEPARATOR .
$this->clean($packageAutoloader->namespace);
$this->filesystem->deleteDir($outputDir);
break;
case Classmap::class:
$outputDir = $this->config->classmap_directory . $package->config->name;
$outputDir = str_replace('\\', DIRECTORY_SEPARATOR, $outputDir);
$outputDir = $this->classmap_directory . DIRECTORY_SEPARATOR . $this->clean($package->config->name);
$this->filesystem->deleteDir($outputDir);
break;
}
Expand All @@ -93,12 +103,12 @@ private function deleteDepTargetDirs($package): void

public function deleteEmptyDirs(): void
{
if (count($this->filesystem->listContents($this->config->dep_directory, true)) === 0) {
$this->filesystem->deleteDir($this->config->dep_directory);
if (count($this->filesystem->listContents($this->dep_directory, true)) === 0) {
$this->filesystem->deleteDir($this->dep_directory);
}

if (count($this->filesystem->listContents($this->config->classmap_directory, true)) === 0) {
$this->filesystem->deleteDir($this->config->classmap_directory);
if (count($this->filesystem->listContents($this->classmap_directory, true)) === 0) {
$this->filesystem->deleteDir($this->classmap_directory);
}
}

Expand All @@ -117,9 +127,7 @@ public function movePackage(Package $package)

foreach ($autoloader->paths as $path) {
$source_path = $this->workingDir . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR
. $package->config->name . DIRECTORY_SEPARATOR . $path;

$source_path = str_replace('/', DIRECTORY_SEPARATOR, $source_path);
. $this->clean($package->config->name) . DIRECTORY_SEPARATOR . $this->clean($path);

$finder->files()->in($source_path);

Expand All @@ -134,7 +142,7 @@ public function movePackage(Package $package)

foreach ($autoloader->files as $file) {
$source_path = $this->workingDir . DIRECTORY_SEPARATOR . 'vendor'
. DIRECTORY_SEPARATOR . $package->config->name;
. DIRECTORY_SEPARATOR . $this->clean($package->config->name);
$finder->files()->name($file)->in($source_path);

foreach ($finder as $foundFile) {
Expand All @@ -146,8 +154,8 @@ public function movePackage(Package $package)
$finder = new Finder();

foreach ($autoloader->paths as $path) {
$source_path = $this->workingDir . DIRECTORY_SEPARATOR . 'vendor'
. DIRECTORY_SEPARATOR . $package->config->name . DIRECTORY_SEPARATOR . $path;
$source_path = $this->workingDir . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR .
$this->clean($package->config->name) . DIRECTORY_SEPARATOR . $this->clean($path);

$finder->files()->in($source_path);

Expand Down Expand Up @@ -181,32 +189,32 @@ public function movePackage(Package $package)
*/
public function moveFile(Package $package, $autoloader, $file, $path = '')
{
// The relative path to the file from the project root.
$sourceFilePath = $this->clean(str_replace($this->workingDir, '', $file->getPathname()));

$packageName = $this->clean($package->config->name);

if ($autoloader instanceof NamespaceAutoloader) {
$namespacePath = $autoloader->getNamespacePath();
$replaceWith = $this->config->dep_directory . $namespacePath;
$targetFile = str_replace($this->workingDir, $replaceWith, $file->getPathname());

$packageVendorPath = DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . $package->config->name
. DIRECTORY_SEPARATOR . $path;
$packageVendorPath = str_replace('/', DIRECTORY_SEPARATOR, $packageVendorPath);
$targetFile = str_replace($packageVendorPath, '', $targetFile);
$namespacePath = $this->clean($autoloader->getNamespacePath());

// TODO: Should $path come from the NameSpaceAutoloader object?
$sourceVendorPath = $this->clean('vendor' . DIRECTORY_SEPARATOR . $packageName
. DIRECTORY_SEPARATOR . $path);

$destinationMozartPath = $this->dep_directory . DIRECTORY_SEPARATOR . $namespacePath;

$targetFilePath = str_ireplace($sourceVendorPath, $destinationMozartPath, $sourceFilePath);
} else {
$namespacePath = $package->config->name;
$replaceWith = $this->config->classmap_directory . DIRECTORY_SEPARATOR . $namespacePath;
$targetFile = str_replace($this->workingDir, $replaceWith, $file->getPathname());

$packageVendorPath = DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . $package->config->name
. DIRECTORY_SEPARATOR;
$packageVendorPath = str_replace('/', DIRECTORY_SEPARATOR, $packageVendorPath);
$targetFile = str_replace($packageVendorPath, DIRECTORY_SEPARATOR, $targetFile);
$sourceVendorPath = 'vendor' . DIRECTORY_SEPARATOR . $packageName;

$destinationMozartPath = $this->classmap_directory . DIRECTORY_SEPARATOR . $packageName;

$targetFilePath = str_ireplace($sourceVendorPath, $destinationMozartPath, $sourceFilePath);
}

$this->filesystem->copy(
str_replace($this->workingDir, '', $file->getPathname()),
$targetFile
);
$this->filesystem->copy($sourceFilePath, $targetFilePath);

return $targetFile;
return $targetFilePath;
}

/**
Expand All @@ -219,7 +227,7 @@ public function moveFile(Package $package, $autoloader, $file, $path = '')
protected function deletePackageVendorDirectories(): void
{
foreach ($this->movedPackages as $movedPackage) {
$packageDir = 'vendor' . DIRECTORY_SEPARATOR . $movedPackage;
$packageDir = 'vendor' . DIRECTORY_SEPARATOR . $this->clean($movedPackage);
if (!is_dir($packageDir) || is_link($packageDir)) {
continue;
}
Expand All @@ -240,4 +248,20 @@ private function dirIsEmpty(string $dir): bool
$di = new \RecursiveDirectoryIterator($dir, \FilesystemIterator::SKIP_DOTS);
return iterator_count($di) === 0;
}

/**
* For Windows & Unix file paths' compatibility.
*
* * Removes duplicate `\` and `/`.
* * Trims them from each end.
* * Replaces them with the OS agnostic DIRECTORY_SEPARATOR.
*
* @param string $path A full or partial filepath.
*
* @return string
*/
protected function clean($path)
{
return trim(preg_replace('/[\/\\\\]+/', DIRECTORY_SEPARATOR, $path), DIRECTORY_SEPARATOR);
}
}
Loading