In Drupal, especially the migrate_drupal module, we often have lines like this, which will break when moving to PSR-4 in #2247991: [May 27] Move all module code from …/lib/Drupal/… to …/src/… for PSR-4.
drupal_get_path('module', 'migrate_drupal') . '/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6VocabularyField.php',
To avoid this kind of trouble (and improve performance as a side effect), we can do this instead, which works both for PSR-0 and PSR-4, if the calling code is in the same subdirectory structure.
dirname(__DIR__) . '/Dump/Drupal6VocabularyField.php',
Some of these were cleaned up in #2083547: PSR-4: Putting it all together, but new ones were introduced in #2121299: Migrate in Core: Drupal 6 to Drupal 8. Maybe the future will introduce even more.
We should reduce the amount of babysitting needed for the PSR-4 transition as much as possible, so let's do this now instead of waiting for the final migration. In an ideal world, #2247991: [May 27] Move all module code from …/lib/Drupal/… to …/src/… for PSR-4 will be nothing more but running the switch-psr4.sh script.
Comment | File | Size | Author |
---|---|---|---|
#16 | interdiff.txt | 1.5 KB | jessebeach |
#16 | ps4r-dir-method-2248149-16.patch | 73.58 KB | jessebeach |
#14 | ps4r-dir-method-2248149-12.patch | 73.55 KB | jessebeach |
#14 | interdiff.txt | 6.4 KB | jessebeach |
#11 | interdiff.txt | 61.82 KB | jessebeach |
Comments
Comment #1
donquixote CreditAttribution: donquixote commentedComment #2
hass CreditAttribution: hass commentedAehm... Some years ago we have been told to use the drupal api and not php dirname with "__DIR__". Was this because of php compatibility?
Comment #3
donquixote CreditAttribution: donquixote commentedThe original and legitimate reason is if you want to reference files in another module, so relative paths won't be reliable. This is because modules can exist in various places such as modules, core/modules, sites/all/modules, sites/all/modules/contrib, etc.
However, since then this "best practice" has been blindly spread and promoted all over the place, without actually thinking about why we do this. So, now people think this is magical, and use it everywhere for no reason.
Comment #4
hass CreditAttribution: hass commentedOk, that makes sense to me :-)
Comment #5
xjmYeah, referencing class filepaths like that is at least icky, if not a bug. Not sure about
__DIR__
though; isn't there an API function that would give us the class filepath?Comment #6
sunThere is no API function for this.
However, given how much code we need to update here, it would make a ton of sense to add a helper method to the Migrate test base class à la
$this->getDumpDirectory()
instead of swapping out one hard-coded location with another.→ If we move the files once again in the future, we just need to change 1 line, instead of 100+ lines.
Comment #7
donquixote CreditAttribution: donquixote commentedIf you look at
MigrateTestBase::prepare()
andMigrateTestBase::loadDumps()
, where these file paths are used:In most cases, this just extracts the class name + namespace from the file name + file contents, which seems pretty stupid to me. Instead we could simply pass the class name with namespace directly.
And this line in loadDumps() also looks weird:
We do this without even checking whether the method exists. And most of the time, the method is just 'load'.
And 'load()' is a misleading name for a method that is mostly about creating db tables.
Imo this entire system is weird. We should go for a simple solution here, just use __DIR__, and then find a way to really clean this up.
Comment #8
donquixote CreditAttribution: donquixote commentedIn general, all this passing around of strings (class names, paths and method names) is inferior to directly instantiating the class and calling the method, IMO.
Directly instantiating and calling can give us IDE inspections with "find usages" and type compatibility checks. Passing around strings accomplishes none of this.
EDIT: I did not study the migrate module a lot, so these are just quick thoughts from the top of my head.
Comment #9
donquixote CreditAttribution: donquixote commentedBtw, the load() has no super method or interface declaration anywhere. Although it definitely should!
Comment #10
xjmActually, this is a beta blocker, because it blocks #2247991: [May 27] Move all module code from …/lib/Drupal/… to …/src/… for PSR-4.
Comment #11
jessebeach CreditAttribution: jessebeach commentedHere's the method that sun suggests in #6.
Comment #13
sun__DIR__ without
dirname()
yields the right path within the /Tests directory.Comment #14
jessebeach CreditAttribution: jessebeach commentedOops, missed this. Rerolling.
Let's keep this issue extremely narrowly focused. It's a beta blocker. If you find code that could do with refactoring, please open another issue.
As far as I can tell, this patch resolves the original issue.
Comment #16
jessebeach CreditAttribution: jessebeach commentedJust saw sun's comment in #13. Rerolled.
Also, I had to put the
getDumpDirectory
inMigrateDrupalTestBase
, notMigrateTestBase
.MigrateDrupalTestBase
is in themigrate_drupal
module which has theDump
directory, whereasMigrateTestBase
is in themigrate
module.Comment #17
benjy CreditAttribution: benjy commentedThis looks like a good clean up to me.
I just wrote some migrations from WordPress the other day and I still used dump files for testing so could we move
getDumpDirectory()
intoMigrateTestBase
instead?Comment #18
jessebeach CreditAttribution: jessebeach commentedMigrateTestBase
is in themigrate
module but the Dump directory is in themigrate_drupal
module, whereMigrateDrupalTestBose
is located. So in order to move the methodgetDumpDirectory
into theMigrateTestBase
class, we'd have to be really specific about the location of the Dump directory. Maybe just usedrupal_get_path
to themigrate
module instead of__dir__
?Comment #19
donquixote CreditAttribution: donquixote commentedI don't care so much for whether we use dirname(__DIR__) or getDumpDirectory().. The latter is probably preferable, since you don't need to be super careful about which directory you are currently in.
But I think the superior solution would be to actually pass around objects instead of file paths.
So, what about the database connection? We simply remove that from the constructor signature, and put it in the load() method instead.
Comment #20
sunAdding the method to the
MigrateDrupalTestBase
class is fine + correct. It is only needed for the tests that extend from the class.Let's not prematurely optimize this. Other test base classes for different migrations can simply copy those 3 lines.
Comment #21
donquixote CreditAttribution: donquixote commentedI am fine if this is committed as proposed in #16.
I would still be interested in some feedback on #19. If you agree this is a reasonable direction, I will post a follow-up and produce a patch.
Comment #22
webchickI don't know about #19 enough to really comment, but happy to knock off a beta blocker. :)
Committed and pushed to 8.x. Thanks!
Comment #24
donquixote CreditAttribution: donquixote commentedFollow-up: #2254157: Refactor Dump classes in migrate_drupal