Skip to content

Commit 5643f1c

Browse files
authored
Merge pull request #46 from thewilkybarkid/classmap
Manipulate the classmap rather than the generated classmap file
2 parents 4ce2449 + d7dff3f commit 5643f1c

5 files changed

Lines changed: 150 additions & 142 deletions

File tree

src/PuliPlugin.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public static function getSubscribedEvents()
4343
return array(
4444
ScriptEvents::POST_INSTALL_CMD => 'listen',
4545
ScriptEvents::POST_UPDATE_CMD => 'listen',
46+
ScriptEvents::PRE_AUTOLOAD_DUMP => 'listen',
4647
ScriptEvents::POST_AUTOLOAD_DUMP => 'listen',
4748
);
4849
}
@@ -78,6 +79,9 @@ public function listen(Event $event)
7879
}
7980

8081
switch ($event->getName()) {
82+
case ScriptEvents::PRE_AUTOLOAD_DUMP:
83+
$this->impl->preAutoloadDump();
84+
break;
8185
case ScriptEvents::POST_AUTOLOAD_DUMP:
8286
$this->impl->postAutoloadDump();
8387
break;

src/PuliPluginImpl.php

Lines changed: 75 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ class PuliPluginImpl
8383
*/
8484
private $rootDir;
8585

86+
/**
87+
* @var bool
88+
*/
89+
private $runPreAutoloadDump = true;
90+
8691
/**
8792
* @var bool
8893
*/
@@ -98,6 +103,11 @@ class PuliPluginImpl
98103
*/
99104
private $initialized = false;
100105

106+
/**
107+
* @var string
108+
*/
109+
private $autoloadFile;
110+
101111
public function __construct(Event $event, PuliRunner $puliRunner = null)
102112
{
103113
$this->composer = $event->getComposer();
@@ -106,29 +116,28 @@ public function __construct(Event $event, PuliRunner $puliRunner = null)
106116
$this->isDev = $event->isDevMode();
107117
$this->puliRunner = $puliRunner;
108118
$this->rootDir = Path::normalize(getcwd());
119+
120+
$vendorDir = $this->config->get('vendor-dir');
121+
122+
// On TravisCI, $vendorDir is a relative path. Probably an old Composer
123+
// build or something. Usually, $vendorDir should be absolute already.
124+
$vendorDir = Path::makeAbsolute($vendorDir, $this->rootDir);
125+
126+
$this->autoloadFile = $vendorDir.'/autoload.php';
109127
}
110128

111-
public function postAutoloadDump()
129+
public function preAutoloadDump()
112130
{
113131
if (!$this->initialized) {
114132
$this->initialize();
115133
}
116134

117135
// This method is called twice. Run it only once.
118-
if (!$this->runPostAutoloadDump) {
136+
if (!$this->runPreAutoloadDump) {
119137
return;
120138
}
121139

122-
$this->runPostAutoloadDump = false;
123-
124-
$vendorDir = $this->config->get('vendor-dir');
125-
126-
// On TravisCI, $vendorDir is a relative path. Probably an old Composer
127-
// build or something. Usually, $vendorDir should be absolute already.
128-
$vendorDir = Path::makeAbsolute($vendorDir, $this->rootDir);
129-
130-
$autoloadFile = $vendorDir.'/autoload.php';
131-
$classMapFile = $vendorDir.'/composer/autoload_classmap.php';
140+
$this->runPreAutoloadDump = false;
132141

133142
try {
134143
$factoryClass = $this->getConfigKey('factory.in.class');
@@ -141,9 +150,51 @@ public function postAutoloadDump()
141150

142151
$factoryFile = Path::makeAbsolute($factoryFile, $this->rootDir);
143152

144-
$this->insertFactoryClassConstant($autoloadFile, $factoryClass);
145-
$this->insertFactoryClassMap($classMapFile, $vendorDir, $factoryClass, $factoryFile);
146-
$this->setBootstrapFile($autoloadFile);
153+
$autoload = $this->composer->getPackage()->getAutoload();
154+
$autoload['classmap'][] = $factoryFile;
155+
156+
$this->composer->getPackage()->setAutoload($autoload);
157+
158+
if (!file_exists($factoryFile)) {
159+
$filesystem = new Filesystem();
160+
// Let Composer find the factory class with a temporary stub
161+
162+
$namespace = explode('\\', ltrim($factoryClass, '\\'));
163+
$className = array_pop($namespace);
164+
165+
if (count($namespace)) {
166+
$stub = '<?php namespace '.implode('\\', $namespace).'; class '.$className.' {}';
167+
} else {
168+
$stub = '<?php class '.$className.' {}';
169+
}
170+
171+
$filesystem->dumpFile($factoryFile, $stub);
172+
}
173+
}
174+
175+
public function postAutoloadDump()
176+
{
177+
if (!$this->initialized) {
178+
$this->initialize();
179+
}
180+
181+
// This method is called twice. Run it only once.
182+
if (!$this->runPostAutoloadDump) {
183+
return;
184+
}
185+
186+
$this->runPostAutoloadDump = false;
187+
188+
try {
189+
$factoryClass = $this->getConfigKey('factory.in.class');
190+
} catch (PuliRunnerException $e) {
191+
$this->printWarning('Could not load Puli configuration', $e);
192+
193+
return;
194+
}
195+
196+
$this->insertFactoryClassConstant($this->autoloadFile, $factoryClass);
197+
$this->setBootstrapFile($this->autoloadFile);
147198
}
148199

149200
/**
@@ -200,6 +251,13 @@ public function postInstall()
200251

201252
private function initialize()
202253
{
254+
if (!file_exists($this->autoloadFile)) {
255+
$filesystem = new Filesystem();
256+
// Avoid problems if using the runner before autoload.php has been
257+
// generated
258+
$filesystem->dumpFile($this->autoloadFile, '');
259+
}
260+
203261
$this->initialized = true;
204262

205263
// Keep the manually set runner
@@ -210,6 +268,7 @@ private function initialize()
210268
$this->puliRunner = new PuliRunner($this->config->get('bin-dir'));
211269
} catch (RuntimeException $e) {
212270
$this->printWarning('Plugin initialization failed', $e);
271+
$this->runPreAutoloadDump = false;
213272
$this->runPostAutoloadDump = false;
214273
$this->runPostInstall = false;
215274
}
@@ -220,6 +279,7 @@ private function initialize()
220279
$this->verifyPuliVersion();
221280
} catch (RuntimeException $e) {
222281
$this->printWarning('Version check failed', $e);
282+
$this->runPreAutoloadDump = false;
223283
$this->runPostAutoloadDump = false;
224284
$this->runPostInstall = false;
225285
}
@@ -439,33 +499,6 @@ private function insertFactoryClassConstant($autoloadFile, $factoryClass)
439499
file_put_contents($autoloadFile, $contents);
440500
}
441501

442-
private function insertFactoryClassMap($classMapFile, $vendorDir, $factoryClass, $factoryFile)
443-
{
444-
if (!file_exists($classMapFile)) {
445-
throw new PuliPluginException(sprintf(
446-
'Could not adjust autoloader: The file %s was not found.',
447-
$classMapFile
448-
));
449-
}
450-
451-
$this->io->write(sprintf('<info>Registering "%s" with the class-map autoloader</info>', $factoryClass));
452-
453-
$relFactoryFile = Path::makeRelative($factoryFile, $vendorDir);
454-
$escFactoryClass = var_export($factoryClass, true);
455-
$escFactoryFile = var_export('/'.$relFactoryFile, true);
456-
$classMap = sprintf("\n %s => \$vendorDir . %s,", $escFactoryClass, $escFactoryFile);
457-
458-
$contents = file_get_contents($classMapFile);
459-
460-
// Regex modifiers:
461-
// "m": \s matches newlines
462-
// "D": $ matches at EOF only
463-
// Translation: insert before the last ");" in the file
464-
$contents = preg_replace('/\n(?=\);\s*$)/mD', "\n".$classMap, $contents);
465-
466-
file_put_contents($classMapFile, $contents);
467-
}
468-
469502
private function setBootstrapFile($autoloadFile)
470503
{
471504
$bootstrapFile = $this->getConfigKey('bootstrap-file');

tests/Fixtures/root/the-vendor/composer/autoload_classmap.php

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)