Skip to content

Commit

Permalink
Merge branch 'master' into autoload-override
Browse files Browse the repository at this point in the history
  • Loading branch information
coenjacobs authored May 23, 2020
2 parents f095c0e + d63631b commit 7ec7e92
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 8 deletions.
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ Mozart requires little configuration. All you need to do is tell it where the bu
"src/"
]
}
}
},
"delete_vendor_directories": true
}
},
```
Expand All @@ -44,14 +45,15 @@ The following configuration values are required:
- `dep_directory` defines the directory the files of the package will be stored in. Note that the directory needs to correspond to the namespace being used in your autoloader and the namespace defined for the bundled packages. Best results are achieved when your projects are using the [PSR-4 autoloader specification](http://www.php-fig.org/psr/psr-4/).
- `classmap_directory` defines the directory files that are being autoloaded through a classmap, will be stored in. Note that this directory needs to be autoloaded by a classmap in your projects autoloader.
- `classmap_prefix` defines the prefix that will be applied to all classes inside the classmap of the package you bundle. Say a class named `Pimple` and the defined prefix of `CJTP_` will result in the class name `CJTP_Pimple`.
- `packages` is an array that defines the packages that need to be processed by Mozart. The array requires the slugs of packages in the same format as provided in your `composer.json`. Mozart will automatically rewrite dependencies of these packages as well. You don't need to add dependencies of these packages to the list.

**Important:** Since Mozart automatically processes the full dependency tree of the packages you specify, you **need to specify all these configuration options**, because you can't reliably determine what kind of autoloaders are being used in the full dependency tree. A package way down the tree might suddenly use a classmap autoloader for example. Make sure you also include the namespace directory and classmap directory in your own autoloader, so they are always loaded.

The following configuration is optional:

The following configuration is optional:

- `delete_vendor_directories` is a boolean flag to indicate if the packages' vendor directories should be deleted after being processed. _default: true_.
- `packages` is an optional array that defines the packages to be processed by Mozart. The array requires the slugs of packages in the same format as provided in your `composer.json`. Mozart will automatically rewrite dependencies of these packages as well. You don't need to add dependencies of these packages to the list. If this field is absent, all packages listed under composer require will be included.
- `override_autoload` a dictionary, keyed with the package names, of autoload settings to replace those in the original packages' `composer.json` `autoload` property.

After Composer has loaded the packages as defined in your `composer.json` file, you can now run `mozart compose` and Mozart will bundle your packages according to the above configuration. It is recommended to dump the autoloader after Mozart has finished running, in case there are new classes or namespaces generated that aren't included in the autoloader yet.

## Scripts
Expand Down
7 changes: 6 additions & 1 deletion src/Console/Commands/Compose.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,17 @@ protected function execute(InputInterface $input, OutputInterface $output)

$config = json_decode(file_get_contents($workingDir . '/composer.json'));
$config = $config->extra->mozart;

$config->dep_namespace = preg_replace("/\\\{2,}$/", "\\", "$config->dep_namespace\\");

$this->config = $config;

$this->mover = new Mover($workingDir, $config);
$this->replacer = new Replacer($workingDir, $config);

$packages = $this->findPackages($config->packages);
$require = empty($config->packages) ? array_keys(get_object_vars($composer->require)) : $config->packages;

$packages = $this->findPackages($require);

$this->movePackages($packages);
$this->replacePackages($packages);
Expand Down
7 changes: 6 additions & 1 deletion src/Mover.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ public function movePackage(Package $package)
$this->movedPackages[] = $package->config->name;
}

$this->deletePackageVendorDirectories();
if (!isset($this->config->delete_vendor_directories) || $this->config->delete_vendor_directories === true) {
$this->deletePackageVendorDirectories();
}
}

/**
Expand Down Expand Up @@ -137,6 +139,9 @@ protected function deletePackageVendorDirectories()
{
foreach ($this->movedPackages as $movedPackage) {
$packageDir = '/vendor/' . $movedPackage;
if (is_link($packageDir)) {
continue;
}
$this->filesystem->deleteDir($packageDir);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Replace/NamespaceReplacer.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public function replace($contents)
{
$searchNamespace = $this->autoloader->getSearchNamespace();
return preg_replace_callback(
'/([^\\?])(' . addslashes($searchNamespace) . '[\\\|;])/U',
'/([^a-zA-Z0-9_\x7f-\xff])((?<!' . addslashes( $this->dep_namespace ) . ')' . addslashes($searchNamespace) . '[\\\|;])/U',
function ($matches) {
return $matches[1] . $this->dep_namespace . $matches[2];
},
Expand Down
14 changes: 14 additions & 0 deletions tests/replacers/NamespaceReplacerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,18 @@ public function it_replaces_partial_namespace_declarations(): void
$contents = $this->replacer->replace($contents);
$this->assertEquals('namespace Prefix\\Test\\Test\\Another;', $contents);
}

/** @test */
public function it_doesnt_prefix_already_prefixed_namespace(): void {
$autoloader = new Psr0();
$autoloader->namespace = 'Test\\Another';

$replacer = new NamespaceReplacer();
$replacer->setAutoloader($autoloader);

$contents = 'namespace Prefix\\Test\\Another;';
$contents = $this->replacer->replace($contents);
$this->assertEquals('namespace Prefix\\Test\\Another;', $contents);
}

}

0 comments on commit 7ec7e92

Please sign in to comment.