Problem/Motivation
As argued in #2462233: Migrations should not use the configuration entity system migrations should not use the config system. Now I agree they should not be config but instead should be plugins. Note the original issue did not suggest plugins, this was an idea of phenaproxima which I now consider doable based on a new, more complete understanding of the plugin system I've acquired during the long and hard debugging of #2605684: Routing silently fails in kernel tests.
Proposed resolution
Make them plugins. The current YML files themselves become a plugin each via a custom discovery. UI and code provided migrations still go into the config active store and retrieved as plugin derivatives.
Benefits of approach
- No more templates, custom to the Migrate API and hard for others to understand.
- No more builders, this now uses derivates like other parts of core. E.g. menu blocks.
- No more config objects but still a simplified YAML file to describe migrations.
Remaining tasks
- Add back a query system. This will be done in a followup. The config entity query is easy to extend for this -- only the
loadRecords
method needs to be overridden. - Dependency/requirements handling is also a followup.
User interface changes
API changes
Migration entity is gone so Migration::create
and Migration::load
calls need to be converted. Migration::create($config)
in tests becomes simply new Migration([], uniqid(), $config);
and the use
statement needs to change from Entity
to Plugin
. Migration::load($id)
becomes \Drupal::service('plugin.manager.migration')->createInstance($id)
. Once you have a Migration
object -- now a plugin -- the methods are the same. A followup will make it necessary to change the use
statement for the MigrationInterface as it will also move from Entity into Plugin.
For code provided migrations here's an example from MigrateTaxonomyTermStubTest
:
Before:
$term_migration = Migration::create($config);
$term_migration->save();
After:
$term_migration = MigrationConfigDeriver::save('terms', $config);
There is no create because, well, there's nothing save-able to create.
Data model changes
Comment | File | Size | Author |
---|---|---|---|
#168 | 2625696-6-168.patch | 193.19 KB | alexpott |
#159 | interdiff.txt | 1.92 KB | benjy |
#159 | 2625696-159.patch | 193.5 KB | benjy |
#157 | interdiff.txt | 3.61 KB | benjy |
#157 | 2625696-156.patch | 193.11 KB | benjy |
Comments
Comment #2
chx CreditAttribution: chx at Smartsheet commentedComment #3
dawehnerIMHO this is a 8.1.x change, because well, 8.0.x is not meant to be for big changes. We have 5 months which is not a long time anyway, but more important, I think we all just care about getting something done, not whether its available directly.
Comment #4
phenaproximaA guarded +1 for this. I wrote some proof-of-concept code on GitHub to show that we can keep our existing YAML files as-is while quietly leveraging the plugin system and moving away from entities. I'm glad the builder system will be gone -- it was always a hack, and it solves the same problem that derivers do.
Overall I think this will allow us to shed a lot of existing code and make the migration system more understandable. @EclipseGc originally gave me the idea :)
Comment #5
catchI also think it's 8.1.x.
The only caveat is it'd be good to ensure that migration source and destinations between modules don't need any changes between 8.0.x and 8.1. so that modules only have to port once.
For actual migrations I'm more concerned with not breaking early use of migrations on 8.0.x in patch releases than keeping 8.0.x and 8.1.x in sync.
Comment #6
chx CreditAttribution: chx at Smartsheet commentedYes, definitely 8.1.x filing under 8.0.x was a mistake. However, upon more reviewing I found that keeping BC is a bit harder than expected -- while the interfaces I looked at yesterday for source and destination doesn't use the migration (mostly), the base class constructors do.
Based on a discussion with alexpott, we will add a MigrationInterface to the Plugin namespace and have a @deprecated one in Entity extend it and implement the ConfigEntityInterface by throwing an exception on save and such.
Comment #7
Gábor HojtsyWait, isn't one of the points of experimental modules that we can still make bigger changes however we want? We did that before the 8 release to migrate out of bounds of whatever process state for the rest of core. Should experimental modules now be in the same process bounds as the rest of core? (Bojhan just proposed last weekend that experimental modules be used to get fast feedback on UX changes / additions in core. If they are bound to a 6 month release / change cycle like this issue suggests, then that does not sound possible to me).
Comment #8
catchContrib modules will hopefully be starting to write migration sources and destinations, and we know that people are using migrate in the wild to upgrade from 6.x-8.x regardless of experimental status.
Those are two of the main things that are going to ensure that when migrate stops being experimental, that people will be able to successfully upgrade sites - so we should try not to break them in patch releases.
So if the changes here come with a backwards compatibility layer, then I'd not have a problem committing them to 8.0.x - means less divergence and means that modules don't have to port twice. Then because it's @internal/experimental, we could remove that backwards compatibility layer in 8.1.x if we want to.
If we absolutely had to break things in a patch release by adding a method to an interface because it's necessary to fix a bug, then that's a different discussion to have. I also think new interfaces/modules that we might add as experimental are a very different category - there's not going to be an API exposed to contrib modules or the urgency to use them in production un the same way.
So moving back to 8.0.x for now - if there are changes that will actually break contrib modules and migrations we can split them out.
Comment #9
benjy CreditAttribution: benjy at PreviousNext commentedI spoke with chx about this when he started but I just wanted to comment publicly that i'm +1 here. I think removing the migration_templates which is a home grown migrate concept is a big win.
It would also be nice to get rid of builders although that might be more tricky. We'll likely have to go back to run-time generation of the sub-migrations, similar to how the load plugins used to work.
Comment #10
xjmI disagree with committing this to 8.0.x; it completely breaks semver. We should commit the change to 8.1.x as soon as it's ready, but not to 8.0.x. The experimental designation is protection for the 8.0 to 8.1 upgrade, not a license to break semver in patch releases.
Comment #11
xjmJust to reiterate "commit it to 8.1.x" does not mean "later". It means right now. 8.1.x is our development branch and we are committed to improving migrate right now.
Comment #12
phenaproximaI'm in favor of this being an 8.1 target. Moving off the entity system is a big enough change to Migrate (mostly under the hood, to be sure, but still a major change) that it doesn't seem appropriate to me to put it into 8.0.x.
Comment #13
chx CreditAttribution: chx at Smartsheet commentedwell then, this is the question: may I move the interface out of entity breaking every migrate plugin out there? Fixing them is a trivial change in the
use
statement.Comment #14
benjy CreditAttribution: benjy at PreviousNext commentedI think we should yes, if this is going into 8.1 we can just write a change record here with the upgrade steps required. Obviously we're trying to keep it simple but updating some use statements falls within that for me.
Comment #15
mikeryanSo, I'm skeptical of making this change, but want to keep an open mind - @chx, please update when your sandbox is stable, and I'll try updating migrate_plus/migrate_tools/migrate_upgrade to use it and see how the DX is affected.
Specific notes:
We are using entityQuery() in migrate_tools, to filter on migration group (functionality provided by migrate_plus). And I for one am capable of imagining any number of query scenarios;P.
I hope that's not true! The template approach makes sense for the Drupal-to-Drupal case so we can, say, make multiple type-specific node migrations from one .yml file, but most custom migration scenarios should be putting migration configuration into config/install. See migrate_example on how this would normally work.
I'm a little vague on how migrations get into the active store in the first place, if not installed from config/install or building templates...
That could work for the straight upgrade-as-is Drupal-to-Drupal case... But what about custom migrations? The builder creates concrete distinct migrations per content type, so you can then tweak field mappings and such for each migration.
Comment #16
chx CreditAttribution: chx at Smartsheet commented> We are using entityQuery() in migrate_tools, to filter on migration group (functionality provided by migrate_plus). And I for one am capable of imagining any number of query scenarios
This is very valuable information. I will look into this; last I checked config query used remarkable little of the config system -- for example, no schema information is used so extending it won't be hard.
> I hope that's not true!
I had many hopes with Drupal 8, most of them are dead.
> I'm a little vague on how migrations get into the active store in the first place,
The UI needs to save things somewhere. What about the config store? Or is it going to be the K-V store? I am wondering. Not sure yet.
> The builder creates concrete distinct migrations per content type, so you can then tweak field mappings and such for each migration.
What you mean simply is that the deriver idea of mine won't work but we need an override like some of the menu link systems because we need an override for plugins created by a deriver. That's fine.
Comment #17
benjy CreditAttribution: benjy at PreviousNext commentedYeah, migrate_ui is using that as well although I don't see why we can't just do what we did for migrate templates in MigrateTemplateStorage, that should be fine once we add some caching #2626488: MigrateTemplateStorage should implement some caching
Comment #18
mikeryanSure, a UI will save things... wherever. But what's the pattern for custom-developed migration modules? Instantiate the migration (in whatever store) in hook_install()? That's something we get for free now with config/install...
Comment #19
chx CreditAttribution: chx at Smartsheet commented> But what's the pattern for custom-developed migration modules? Instantiate the migration (in whatever store) in hook_install()?
Put the YAML files in [moduleroot/]migrations. End. (The sandbox currently picks them up from migration_templates for BC and easier development of this system.)
Comment #20
mikeryanAh, so the YAML files in the migrations directory are automatically installed, I didn't get that. Thanks.
Comment #21
chx CreditAttribution: chx at Smartsheet commented> Ah, so the YAML files in the migrations directory are automatically installed,
No, there is no such thing as installation. They are simply plugin definitions.
Comment #22
heddnI'm very curious about the DX we get with this change. Are there examples yet that will show the before/after picture of what converting to plugins will introduce? I'm already seeing a lot of traffic on migrate_source_csv and want to be ahead of the game if things are going to change significantly.
Comment #23
dawehnerAs far as I understand its basically moving all existing migrate.migration.yml files to a new subfolder, that's it.
Instead of then using config_devel or drush cedit or such, you'd just clear the plugin cache and have new versions of your migrations.
Comment #24
chx CreditAttribution: chx at Smartsheet commentedNot even that, we can have the discovery pick up from the old templates directory too. In fact, that's what the current sandbox code does.
The only big change I see on the road ahead is the nuking of builder plugins in favor of derivers.
Comment #25
chx CreditAttribution: chx at Smartsheet commentedIf this passes I will be surprised. But! I saw one test passing so let's see.
Comment #27
chx CreditAttribution: chx at Smartsheet commentedMeh I was developing against 8.0.x , I wanted a bot run against that. I will move this back to 8.1 once the testing finished.
Comment #28
chx CreditAttribution: chx at Smartsheet commentedComment #30
chx CreditAttribution: chx at Smartsheet commentedReally annoying :( I rolled this patch with git diff origin/8.1.x > 2625696_30.patch surely it will apply.
Edit: bot fail due to https://dispatcher.drupalci.org/job/default/55864/ DCI_CoreBranch 8.0.x
Comment #32
chx CreditAttribution: chx at Smartsheet commentedI wish there was a way to delete unnecessary comments.
Comment #33
chx CreditAttribution: chx at Smartsheet commentedComment #36
chx CreditAttribution: chx at Smartsheet commentedComment #37
chx CreditAttribution: chx at Smartsheet commentedComment #38
chx CreditAttribution: chx at Smartsheet commentedComment #39
chx CreditAttribution: chx at Smartsheet commentedComment #40
benjy CreditAttribution: benjy at PreviousNext commentedNice work so far :)
Seems this is a common action, maybe we should add a getMigration or similar helper to the test base class?
bad merge.
Interesting, I guess this is a side-effect of the migration properties changing. Certainly could be un-expected that a definition could change during the life of a plugin. Guess we don't have much choice?
Also, s/accomodate/accommodate
Does the id need a preg_quote? Not sure if plugin ids can have hyphens in their names maybe?
debug code?
Ouch, hopefully this won't be a common pattern but maybe we could create a follow-up to discuss other solutions?
Double space.
Will this bubble up somewhere else?
We squash the requirement errors? Should we at least log these? If you had a schema mismatch, it would be hard to know?
Also, we don't call checkRequirements on the d6_node_type source?
Can we comment what exceptions we're squashing here.
All this looks very similar to the D6 version, shall we add a base class?
Debug?
Not sure what this means to delete the plugin instance? But we should remove the comment or something?
Debug code.
and here.
Thanks for bringing this test coverage back!
Comments here would be good.
Can we inject this into the migrations now.
Comment #41
chx CreditAttribution: chx at Smartsheet commentedA few quick notes as I have a flight to catch: most of those return; statements are not debug code and have a @todo attached, they are killed off until dependencies are added back. The one in MigrateDrupalTestBase::installMigrations is a tentative one before killing off the method (in a followup?): what does it mean to install a migration now? Nothing. That's not an operation we need to do. Migrations simply are.
Comment #43
chx CreditAttribution: chx at Smartsheet commentedComment #44
chx CreditAttribution: chx at Smartsheet commentedComment #46
chx CreditAttribution: chx at Smartsheet commentedTry #2.
Comment #48
mikeryanI've added issues to POC this against my contrib modules: #2667366: Make migrate_plus work with Drupal 8.1.x, #2667368: Make migrate_tools work with Drupal 8.1.x, #2667370: POC of migrations-as-plugins. Hopefully, this coming weekend I'll have some time to see how it affects in particular migrate_plus (and the infamous beer example) and migrate_tools.
Could we have an explicit list of anticipated benefits in the issue summary?
Thanks.
Comment #49
chx CreditAttribution: chx at Smartsheet commentedMost tests should pass. Drupal\Tests\migrate\Unit\process\MigrationTest won't but then again I can't be bothered, I will write a new test once this is in.
Most bugs were due to preg_quoting the id revealing we still passed in :* when that wasnt supposed to happen and since :* unquoted merrily matched nothing it worked prior.
As for benefits, removing migration templates is the biggest win. Perhaps the only but that's enough. And of course we no longer pollute the config system. There's a MigrationConfigDeriver for UI based migrations saved into config.
Comment #50
chx CreditAttribution: chx at Smartsheet commentedA few more :* fixed.
Comment #52
chx CreditAttribution: chx at Smartsheet commentedHrm, that getMigration refactor didn't work out as planned. Here, this is better.
Comment #54
chx CreditAttribution: chx at Smartsheet commentedComment #56
chx CreditAttribution: chx at Smartsheet commentedThis concludes the getMigration() refactor.
Comment #57
benjy CreditAttribution: benjy at PreviousNext commentedThis is looking great, few doc fixes and problems noted below. Tried to ignore any existing problems in code that was just moved, looking forward to the follow-ups where we can get rid of many uses of \Drupal, seems we have a lot from the config entity approach.
Missing docs.
Should this be un-commented? Or, add a TODO?
Extra new line.
We can just move this to the interface and inheritdoc as mentioned in 1
We may as well use getMigration() where we can.
$migratio_plugin_manager is type-hinted with the wrong interface. We have a migrate specific one.
Add a todo here.
Need a comment here.
Comment here as well please. Why do we hide the requirement failures.
Comment #58
chx CreditAttribution: chx at Smartsheet commentedComment #59
chx CreditAttribution: chx at Smartsheet commentedThere was a $yaml_discovery->addTranslatableProperty('label', 'title_context'); left in the MigrationPluginManager -- the manager was strongly influenced (ahem) by MenuLinkManager and such but as we do not actually provide a context for title we do not need this.
Comment #60
benjy CreditAttribution: benjy at PreviousNext commentedSpoke through a few more points on IRC, hard to review anymore with the excitement of getting rid of templates. My main concern was removing the dependency handling but chx plans on working on those right after this issue and the current patch is already big enough. RTBC from me.
Comment #61
benjy CreditAttribution: benjy at PreviousNext commentedComment #62
andypostComment #63
chx CreditAttribution: chx at Smartsheet commentedDo we need a change record? Unless you are writing a migrate UI which benjy and mikeryan do you don't need to do anything. Your migration YML can be the same, your source, process, destination plugins will still work. The builder plugins were never documented on https://www.drupal.org/node/2127611 . So ... why needs change record?
Comment #64
dawehnerThere has been some discussion around using change records as some sort of replacement for changelog.txt. Given that maybe this issue is a big enough change to be mentioned?
Comment #65
alexpottIt'd be great to hear from @mikeryan again after the comment #48:
Especially as @mikeryan has been a supporter of keeping migrate in config.
BTW as maintainer of a lot of the config code - I'm super happy by this approach - I've not yet reviewed the code in detail.
Comment #66
chx CreditAttribution: chx at Smartsheet commentedI wrote a change record. I found something copied from MenuLinkManager which is not necessary so there's an tiny change attached but while at it I believe I found a doxygen bug in setCacheBackend, will discuss with the plugin people and file a documentation bug.
Comment #67
chx CreditAttribution: chx at Smartsheet commentedLet's try the interdiff again. Varnish went bonkers over my the previous attempt.
Comment #68
andypostAt least https://www.drupal.org/node/2527568 should be updated cos templates are useless now
Comment #69
andypostOverall looks great, mostly nits but some require to be added to CR
this should be added to change record as before-after
is this changes in scope?
once there's no more entity_load() then change record should point a way to retrieve migrations
probably this one should be used to load them.
Is there any helpers for?
Why that code commented with hash?
the related issue does not describe what to do
strange way to pass deps, but arguments whould be properly type-hinted at least for MigrationPluginManagerInterface
Why they optional?
This should be in change record too, new way to get migrations!
Comment #70
chx CreditAttribution: chx at Smartsheet commentedThanks for the review, I edited the CR.
>Why that code commented with hash?
> the related issue does not describe what to do
To make it stand out more. None of the child issues describe what to do, they are placeholders. We will get there.
> strange way to pass deps, but arguments whould be properly type-hinted at least for MigrationPluginManagerInterface . Why they optional?
If there's a reroll I will do it if not I will do it in the dependency followup.. they are optional so that you can just do
MigrationConfigDeriver::save()
but they can be passed in for, I dunno, testing.Comment #71
alexpottIn an ideal world this issue would be 100% complete on commit - however it does make sense to cleanups in separate issues as longs this issue contains all the API changes.
Drupal\migrate\Entity\MigrationInterface
- as the issue summary hints at a good idea would be to do this is a followup. However I think we should put the correct interface in place in the issue and just makeDrupal\migrate\Entity\MigrationInterface
extend from it and add a @todo to remove it.This class no longer exists
Drupal\migrate\Entity\Migration
Missing the rest of it... mind you these are all being removed.
I think commenting out this is a mistake. Looking at
Drupal\migrate\Plugin\Migration::checkRequirements()
- that's still doing an entity load multiple.I don't think we can typehint
$plugin_definition
as there have been moves to make this an object. It ismixed
in the docblock. Also isn't{@inheritdoc}
appropriate here?Does this whole thing exist as a bc layer for customised migrations? What happens when existing sites have a config for an existing plugin? And does this class have any test coverage?
So as the entity no longer exists with the prefix
'migrate.migration.'
this is invalid configuration. What happens when the migrate UI reintroduces the config entity?We need to catch exceptions here and re-throw with the information of what file has caused the problem - otherwise this can be hard to debug. (And yes we should do this in YamlDiscovery too - but not in this issue.)
Is the fact that both migration_templates and migrations are scanned tested anywhere? Also I think this could be clearly documented on the class doc.
This does not look good - I think we should try to make sure this test coverage is fixed in this issue.
Can't all the stuff before the
if
be inside theif
Why are exceptions being thrown and why are we catching the generic exception and saying nothing - looks dangerous.
Catching the generic exception and doing nothing looks super dangerous. Apparently this one is something about dependencies.
This looks like an abstract NodeDeriverBase could be useful. Or maybe even a more generic trait.
Does this need a separate issue? It looks like
installMigrations
can just be removed.I think we can just delete this code and move on.
I'm really wary of leaving the dependency / requirements work till later.
This catch looks dangerous too.
Comment #72
mikeryanI did start working on #2667366: Make migrate_plus work with Drupal 8.1.x (migrate_plus) and #2667368: Make migrate_tools work with Drupal 8.1.x (migrate_tools) with this patch yesterday, didn't have time to write up what my experience was so far until tonight...
The migrate_example module was simple enough - just moved the migration .yml files from config/install to the migrations directory (something that definitely needs to be in the change record). Well, I also had to hack the connection key into each migration, until I figure out how to implement the merge-the-migration-group's-config-into-each-migration with hook_migration_plugins(). But, pleased that at least a simple migration scenario works with no changes of substance.
First pass at implementing drush migrate-status, replacing the EntityQuery with plugin discovery, died a horrible death:
The problem here being that the d6_node migration plugin in the node module is referencing the D6NodeDeriver class in migrate_drupal, and I did not have migrate_drupal enabled. chx feels that all the Drupal migration plugins should be in migrate_drupal, although I still feel that the ideal model is that each module should be responsible for its own plugins. Anyway, either all the plugins should move to migrate_drupal, or D6NodeDeriver/D7NodeDeriver should move to the node module.
A more basic issue is, the drush migrate-status command is supposed to list any "available" (as in, "I can run them now") migrations. So, if I enable migrate_example and run drush ms, I expect to see the four migrations beer_term, beer_user, beer_node, and beer_comment listed. This is how it currently works - the migrations of interest to migrate-status are the active configuration entities, easily discovered with an entityQuery(). If I were doing a Drupal upgrade, the configuration process would create only those configuration entities that are relevant to the particular site being migrated (this is why we have templates), and migrate-status equally easily finds those.
So, I'm struggling to see how that works with migrations-as-plugins. Plugin-based discovery is going to discover all migration plugins - i.e., all the migrations defined in all enabled core modules. It's not clear to me how to filter out all the irrelevant plugins. This would apply in the upgrade use case as well - if I don't have the aggregator module enabled on my D6 site, I don't want to run the d6_aggregator_item (not to mention the d7_aggregator_item) migration when upgrading. Is this an issue that's going to be addressed in the dependency follow-up?
Apart from figuring out how that will work, though, the only change to the drush commands was to replace
Migration::load($migration_id)
calls with\Drupal::service('plugin.manager.migration')->createInstance($migration_id)
, so that's encouraging. The UI, based on ConfigEntityListBuilder and EntityForm, is going to be more work though.The next step will be figuring out how this applies to the upgrade process (#2667370: POC of migrations-as-plugins). I won't have a good chunk of time to dive into that before this weekend (if even then), and I'm actually curious how chx and benjy see the plugin approach working in practice here (hint hint, if one of you has time to try a patch in the next few days...).
Also when I have a chance, I need to understand derivers better... I'm not quite clear on how one will, say, customize field mappings on a per-node-type basis as builders support now.
Comment #73
alexpottThere is other contrib that might want the YAML discovery of one plugin per file. I think it is worth splitting that out into another patch so we can add tests and generalise.
Comment #74
benjy CreditAttribution: benjy at PreviousNext commentedThis is already a problem in HEAD, see #2560795: Source plugins have a hidden dependency on migrate_drupal and #2600926: Allow annotations to inherit across namespaces
Comment #75
chx CreditAttribution: chx at Smartsheet commented> chx feels that all the Drupal migration plugins should be in migrate_drupal
But I already said I won't move them back and anyways my plans to just get this in quick has been completely killed by alexpott's review where he doesn't want checkRequirements and perhaps even the dependency checks to be redone here. I was strongly inclined to won't fix it reading his review yesterday but yesterday I was very tired so I thought I will sleep on it. Well, now I did, and I still do not feel like continuing this at all. Heaping everything in one patch is not going to work, but of course, I can do it if I must.
Comment #76
alexpottI've created #2671034: Create plugin per file YAML discovery to handle the generic plugin discovery.
Also I've discussed this issue with @catch. Whilst I'm disappointed that d.o does not yet support feature branches and that committing this will regress existing functionality, I concede that managing this in a mega-patch will be difficult. Therefore let's punt the dependency and checkRequirements stuff to a followup patch that should be a major and tagged with "migrate critical".
However I still think we need to address everything else from #71 and subsequent reviews.
I think we need to remove the entire config integration as providing this should be the remit of the module that provides the config entity type that configures migrate plugins. For me, leaving this in core is dangerous (because what about existing migration config in a live site) and confusing.
Comment #77
benjy CreditAttribution: benjy at PreviousNext commentedI've been thinking about this and I think that does make sense. The config isn't needed to run the migrations, it is only really needed to support the tooling outside of core so that could quite easily be done from contrib. I could put the ConfigEntity definition into http://drupal.org/project/migrate_api which is a module specifically designed to be a dependency for migrate-contrib tooling.
Comment #78
chx CreditAttribution: chx commentedI removed the config deriver, fixed MigrateTaxonomyTermStubTest accordingly. The relevant concerns were addressed, the rest already has followups.
Comment #79
chx CreditAttribution: chx commentedFixed a braino in the new doxygen. Note I didn't move the interface as I am unable to get git to recognize the change and it pushes the patch to be +20k . No point.
Comment #80
benjy CreditAttribution: benjy at PreviousNext commentedReviewing the interdiffs they look good to me, shouldn't we also remove all the schema to do with the config entity here?
Comment #81
alexpott@benjy yep you are right - core shouldn't have any remnant of the migrations as config entities at all.
Comment #82
chx CreditAttribution: chx commentedStill objecting for patch size reasons. I haven't deleted derivers either.
Comment #83
chx CreditAttribution: chx commentedBut, here it is.
Comment #84
alexpottUsing the new #2671034: Create plugin per file YAML discovery and fixing some coding standards stuff.
Comment #85
benjy CreditAttribution: benjy at PreviousNext commentedI believes all of alexpott's feedback from #71 has been done and the per plugin file YAML patch was merged so back to RTBC.
Comment #86
alexpottThe biggest worry about going forward here is the affect on the Drupal Upgrade module ie. #2667370: POC of migrations-as-plugins as that is the module we want to put into 8.1.0 as an experimental module.
Comment #87
alexpottI don't think the derivers should be reaching into the
D6NodeDeriver
to get code they need - let's encapsulate that in a trait.Comment #89
chx CreditAttribution: chx commentedThe trait is a good idea but regarding the renames which caused the fail: http://webchick.net/please-stop-eating-baby-kittens :P
Comment #90
alexpott@chx I was playing around with idea of move them but I didn;t mean to post a patch that did - sorry. I'm torn about the location of the derivers - but I can't work out what to do with the cck deriver and service. I guess we could work some of this out with the dependency stuff. But it feels off to move this stuff about again.
Interdiff with the last working patch - #84.
Comment #92
alexpottOk It is official I can't roll patches... so as the D*NodeDerivers obviously want me to move them and this time I've run the tests locally. They definitely should be part of node and not migrate Drupal - and then we only have the cck one to work what to do with.
Comment #93
alexpottThe latest patches just moved stuff about.
Comment #94
chx CreditAttribution: chx at Smartsheet commentedYes, I wanted to RTBC back too. Thanks.
Comment #95
alexpottI'm going to commit this now to give us the chance to get #2666640: Readd dependencies and such to migration done and then make the necessary changes to migrate_drupal and get that in core as an experimental module. There is a chance that this patch will be reverted if we decide that getting migrate_drupal in core is more important. However at least doing this now gives us a chance to do this.
Committed 694994f and pushed to 8.1.x. Thanks!
Comment #96
benjy CreditAttribution: benjy at PreviousNext commentedThree of the follow-ups are green if someone wants to review:
#2666640: Readd dependencies and such to migration
#2676258: Nuke builder plugins and migration storage
#2667620: Rewrite Drupal\Tests\migrate\Unit\process\MigrationTest
Comment #98
xjmSorry folks but we need to revert this, for two reasons:
Based on the followups above, it sounds like this might actually be a case for an official feature branch of Drupal 8 in the core repository, despite Migrate being experimental. We also should do what we can to make sure this work can go forward too and potentially land in 8.2.x soon.
Also, I think this issue will need subsystem, framework, and release manager signoff to go in, because it significantly impacts the subsystem, the architecture, and the release timeline and goals. @alexpott's commit is an implicit framework manager signoff, but we should probably discuss more given that I'm reverting this for release management reasons. It also sounds as though there was not consensus within the Migrate subsystem maintainers so that needs to be sorted too.
Finally, @alexpott previously suggested that with this being outstanding, we should consider marking Migrate itself alpha instead of beta. That's something we can address in #2656994: Experimental modules should have their own version numbers.
Comment #99
chx CreditAttribution: chx at Smartsheet commentedThanks for coordinating this with us. While I could say how close dependencies were and we were ready to give a hand to core UI if necessary I won't. I am done with migrate. I am unfollowing this and every other issue. I do not need people attacking me on Twitter for a BC break which gets reverted two days later with zero coordination.
Comment #100
benjy CreditAttribution: benjy at PreviousNext commentedYeah this is really disappointing, especially given I spent most the weekend working on the follow-ups including the dependency patch which is pretty much ready.
I pinged alexpott offering to chip-in with any changes that would be required with the UI off the back of this issue, even though, I really didn't want anything to do with it.
I don't know where those sounds are coming from, it would be nice if they spoke up directly to another migrate maintainer in #drupal-migrate
Comment #101
catchJust a note that we’d like to not add major new functionality during the beta, like migrate UI, so not breaking that just before beta1 was important.
However since this is clean-up and migrate will be in alpha generally, it should be fine to be re-committed during the beta - we just don’t want to break migrate UI or other key functionality at the same time.
Comment #103
catchRe-rolled, hopefully tests will run at least.
Comment #105
benjy CreditAttribution: benjy at PreviousNext commentedI've re-rolled again, the last re-roll left the migration class in the entity namespace which of course broke every test.
I had to bring in a a few changes from the dependency patch so we can load multiple migrations at once, I also added a way to load migrations based on a tag to the plugin manager as that was a feature of the entity storage. Most of the changes were against the migrate_drupal_ui, which needs some attention in general.
I had a failure on the UI test locally regarding not being able to set the "driver", i'm wondering if that's because I only have mysql available.
I think we can probably remove some of the "Needs xyz review" tags from this issue now? I'll let someone else do that.
Comment #106
benjy CreditAttribution: benjy at PreviousNext commentedComment #107
benjy CreditAttribution: benjy at PreviousNext commentedOK, this is all I have time for tonight. It fixes all the obvious issues, but the UI tests are still failing. Didn't look into why and the UI just swallows the errors so there is nothing in the simpletest output.
Comment #110
benjy CreditAttribution: benjy at PreviousNext commentedOK, this brings back the dependencies stuff which I wrote in #2666640: Readd dependencies and such to migration
Comment #112
alexpottFixing some of the fails...
Comment #114
alexpottSo we have a chicken and egg situation - we need the source credential whilst instantiating the plugins but in the previous patch they were only set on the plugin after...
Comment #116
alexpottFixing one of the test fails
Comment #119
benjy CreditAttribution: benjy at PreviousNext commentedI'm not sure what is going on in the file source but I removed that for now, it doesn't make any sense to me, its using the destination config to do something in the source but then I can't see anything been done with that data until the destination anyway? Alas, it will need some manual testing and inspection before commit.
The MigrationCreationTrait was manually calling checkRequirements() on the source and the destination rather than calling checkRequirements() on the migration itself?
These migrations are still failing:
A backtrace from DrupalSqlBase::checkRequirements() would probably help figure these out.
Comment #121
alexpottThe 10 files in the d6 migration is interesting... the files table in D6 looks like this...
So 4 is the correct number as temp files are not migrated.
Comment #122
alexpottThis code is problematic because if we didn't add the database fallback thing that the source stuff needs to be somehow set on the source plugin created here.
Comment #123
xjmThe committers discussed this earlier in the week and as catch suggests in #101 we'd like to still try to get this into 8.1.x, especially if it can go in without regressions before a second beta. So moving back to the 8.1.x queue for visibility.
Comment #124
benjy CreditAttribution: benjy at PreviousNext commentedWhat makes you say temporary files are not migrated?
Comment #125
benjy CreditAttribution: benjy at PreviousNext commentedYeah that files issue is a good one, heres what it looks like:
The same issue has been mentioned by others in IRC and on the support forums: https://www.drupal.org/node/2681475 so its a pre-existing in HEAD. You can see the issue in the image, it shows files belonging to other users, and the weird ones are the picture files for users who had a empty picture in the source data.
I can't explain yet how this ever passed unless for some reason, the d6_user_picture_file migration was not running previously which would imply an issue with dependencies.
Comment #126
benjy CreditAttribution: benjy at PreviousNext commentedI've opened #2681505: Arbitrary files are created when migrating users with an empty picture although the UI tests fail there as well with
Found 0 file entities, expected 4.
because the UI was never really working for files and it just so happened that the UI got four bogus profile files rather than the 4 actual files it was expecting. See screenshot after running the Upgrade UI test.Comment #127
benjy CreditAttribution: benjy at PreviousNext commentedOK, this fixes MigrateUpgrade6Test, it includes #2681505: Arbitrary files are created when migrating users with an empty picture as well and you can see from the image in #125, that 6 is the correct amount of files to be asserting for.
Comment #129
alexpott@benjy the problem we have is that we're still just relying on the state fallback for the database - which in itself feels wrong. We're at an interesting place there is a tiny amount of configuration that is necessary for migrations... the source database and the source base path... and actually the list of migrations to perform.
Comment #130
benjy CreditAttribution: benjy at PreviousNext commented@alexpott, yes I understand that, but that doesn't take away from the files issue i fixed in #127? Can we commit this with the fallback in place here and then remove it in a follow-up or do you want to do it all here?
Comment #131
alexpottWell the fallback will work for the database but for the source base path?
Comment #132
benjy CreditAttribution: benjy at PreviousNext commentedThe only quick workaround I can think of is hard-coding the logic currently in getMigrations() to do with the source base path into the batch runner when the migrations are created :/
This patch should be green, fixed an issue in migration creation trait. Also reverted back to just manually checking the requirements on the source/destination which we should create a follow-up to fix.
Comment #133
alexpottWe need to remove this hack though...
Comment #134
benjy CreditAttribution: benjy at PreviousNext commentedYes, this line of code is confusing and obviously doesn't have any test coverage. The destination simply sticks the two values back together before doing anything with it:
$source = $this->configuration['source_base_path'] . $file;
I actually think we should just delete that line in the source and then add a new test to ensure that source_base_path gets into the destination and finally hardcode that logic for entity:file I mentioned above, into the batch runner when it does a createInstances(). That will get us finished here and we can fix properly in a follow-up?
Comment #135
benjy CreditAttribution: benjy at PreviousNext commentedOK, i've reverted the change in the D7 file source, we can fix that in #2577871: d7_file plugin should receive source_base_path configuration option
I've created an issue for the checkRequirements() calls I had to revert in the last patch: #2681867: Drupal Upgrade UI should validate the entire migration, not the source and destination individually
I've created #2681869: Provide clean way to merge configuration into migration plugins to remove the manual setting of the destination config in the batch runner and generically solve how we're going to allow sources and destinations to get their requirements.
I had to fix the source base path in the D6 test, that was why no files were been migrated for the D6 tests, as i reported in #2681539: MigrateUpgrade6Test does not migrate files
There is certainly plenty of ugly happening with the latest fixes required to get the UI green but this patch is nearly 200kb already. If we commit as is to 8.2.x then work on all the follow-ups and once it's all ready, back port to 8.1 that would be the best way forward IMO.
Comment #136
alexpottRe-rolled as #2681505: Arbitrary files are created when migrating users with an empty picture has been committed. @benjy nice job on creating the followups. I've closed #2666640: Readd dependencies and such to migration as that is now redundant. The patch added does a bit of clean up - but there are still two references to #2666640: Readd dependencies and such to migration that need removing.
I also discussed the issue with @benjy on IRC. I think the state fallback for source databases and the way source base path is set are both not ideal but also HEAD is not ideal. Given that we have no regressions here I think fixing this so any migration can declare and get its requirements in #2681869: Provide clean way to merge configuration into migration plugins makes sense.
Furthermore whilst reviewing MigrateCreationTrait I've realised two things:
The latter is addressed by the patch added because getSourceDatabaseConnection() was added by it.
I think once the incorrect @todo's are addressed this patch is ready for serious review and consideration for 8.2.x. I think that in order to get this in 8.1.x-beta we need to get a certain amount of the followups done so we can cherry-pick the lot in one go. This way the patch does not put 8.1.0 at risk and can go there if we get the followups done in time BUT also the patch does not become a 500k unreviewable monster. (@benjy mentioned that doing something like is @catch's idea).
The great thing is that we've got to the point were they are no regressions over what is in HEAD for the purposes of migrate UI. benjy++
Comment #137
quietone CreditAttribution: quietone as a volunteer commentedJust starting using code sniffer in the new IDE and currently get way too much info. But spotted this in all that.
Missing @param for MigrationPluginManagerInterface $migration_plugin_manager.
And needs a use statement for the MigratePluginManager.
Comment #138
alexpottPatch addresses #137 and also fixes a lot of other coding standards things noticed by phpcs that are in scope.
Comment #139
benjy CreditAttribution: benjy at PreviousNext commentedI refined it so we're only catching a database exception now instead of all exceptions and documented why that is so. I also added a test and fixed an issue todo with submitting the UI form with invalid database credentials.
Comment #141
benjy CreditAttribution: benjy at PreviousNext commentedBad assumption about the driver.
Comment #143
alexpottsqlite doesn't use passwords... let's just change the database and assert on migrate ui's message. Also we need to add proper requirements checking to the FieldInstance source plugins.
Comment #144
benjy CreditAttribution: benjy at PreviousNext commentedThanks for fixing the sqlite issue.
I'm not sure if the tableExists checks are correct here or not, we usually rely on the source_provider for the requirement check. If the source provider exists, then so should the tables?
Comment #145
alexpott@benjy but these are being used in the derivers it is bit of a different situation.
Also I think we need to get #2683579: Improve migrate UI tests in first because it properly tests the source_base_path setting through the UI and we're changing how this is configured on the migrations in this patch.
Comment #146
benjy CreditAttribution: benjy at PreviousNext commentedI added the source_provider rather than the table exist checks. interdiff is against #141.
Comment #148
alexpottRerolled...
Comment #149
chx CreditAttribution: chx at Smartsheet commentedSo I diffed to the state when it was committed last and did a through review and most of this looks straightforward requirements and dependency resurrection (although obviously a huge effort: thanks benjy and alexpott) the only weird thing is the file change in the dump from 0 to 6 but that's just a reverse of #2681505: Arbitrary files are created when migrating users with an empty picture since files now work properly.
Also, the MigrationCreateTrait todo saying "The trait no longer creates migrations" is the kind of funny one usually finds only on Raymond Chen's The Old New Thing or TheDailyWTF.
Ps. I reviewed only because benjy asked. This doesn't change anything involvement level wise.
Comment #150
alexpottI've merged this and #2683579: Improve migrate UI tests and the UI tests are still green so we've not broken the source_base_path UI here. Depending on which issue gets in first one will need a reroll.
Comment #152
alexpottWwhat I don't understand is how this patch fixes the files migrate in the UI test - ah I see...
But this is the bit is not quite right... however this is fixed in #2683579: Improve migrate UI tests.
I've merged the patches locally and can confirm that the UI tests still pass.
[Edit: for clarity]
Comment #153
alexpottI've deleted the comment #151 because it is a red herring and distracting. So I think it is okay if #148 goes in and we fix the UI test to use a custom source base path in #2683579: Improve migrate UI tests.
Given the effort that has go into this patch I think it deserves first bite.
Comment #154
catchStarted reviewing this, didn't finish a full pass. I already reviewed the original patch here and was mostly happy with it, so not much new here mostly minor.
Sentence is a bit odd, and it could do with an explanation why.
Very minor but 'derivative migrations' and 'derived migrations' are used almost interchangeably here.
preg_grep()++
It might help to explicitly point out that $dependency_graph will hold all dependencies, and $requirement_graph will hold only the required ones. Would almost call $requirement_graph $required_dependency_graph.
I can't see why $different = TRUE has to be tracked, this looks the same as if (!empty($migration_dependencies['optional'])) - which would also be more self-explanatory.
Also $graph_object being set twice I had to read a couple of times. I think we could do $dependency_graph = (new Graph($dependency_graph)->searchAndSort()?
Needs the parentheses.
IDs
ID
Since it's multiple instances should this be 'If an instance cannot be created' instead of 'If the...'
ID again.
What about nuking it and putting it back again? Assuming we fix the @todo soonish don't really mind though.
Shouldn't we trigger_error() or something when there's an exception?
Also shouldn't the try/catch be for each individual row? It's not clear at all from here what the implications are of the exception being tried/caught - but if we can eat the exception, I'd expect later rows to not be blocked on it. If we can't eat it, we should at least log an error.
Drupal Drupal Drupal Drupal, Drupal.
Again no need to log anything here?
IDs
retrieved data in form storage.
Hmm so this isn't really exceptional, just means CCK was not installed?
Shouldn't we still show an error in this case even if not fatal?
Comment #155
benjy CreditAttribution: benjy at PreviousNext commentedI missed the first part of 5 regarding $different, will do that next. 12 needs more looking into as I'm not sure what is being caught there. Rest is done.
Comment #157
benjy CreditAttribution: benjy at PreviousNext commentedRemaining feedback resolved. The exception only needed to be the requirements exception for the same reason as the derivers.
Fixed the tests after a conflict with #2225477: Add migrate sources and destinations for D6 i18n variables
Comment #159
benjy CreditAttribution: benjy at PreviousNext commentedFixes the two failing tests that were introduced in the last patch. I had to catch the database exception for the exact same reason as the derivers.
Comment #160
vasi CreditAttribution: vasi at Evolving Web commentedI may be misunderstanding things, but I tried this to get a list of migrations:
This currently seems to fail for me in most situations. If I enable just the migrate module, it fails because D6NodeDeriver tries to get the service "plugin.manager.migrate.cckfield", that lives in migrate_drupal. If I enable migrate_drupal, it fails because the migrate_drupal database is not configured. I suppose if I configured a DB it would likely work, but we have to assume some people will use migrations that have nothing to do with upgrades.
* Is my code snippet the right way to do this?
* How do we distinguish between migrations that exist, and migrations that are ready to run?
** Eg: Should we make the D6/D7 derivers simply yield nothing when the migrate database is not configured?
** Should dependencies factor into this?
Comment #161
benjy CreditAttribution: benjy at PreviousNext commented@vasi, where are you doing that? Seems like something that would be done in a migrate contrib project. The dependency issue you describe already exists in core, see #2560795: Source plugins have a hidden dependency on migrate_drupal - we did discuss moving D6Deriver back to migrate_drupal earlier in this issue which would solve the problem.
Theres a follow-up to work out how sources/destinations get their configuration injected, as you mention, it currently throws an error connecting if you don't have a source database configured. We can discuss whether migrations that don't have their config should be silently skipped in #2681869: Provide clean way to merge configuration into migration plugins
Comment #162
alexpott@vasi - good question - see Drupal\migrate_drupal\MigrationCreationTrait::getMigrations() - although I'm inclined to agree that
$migrations = $migration_manager->createInstances([]);
should work and only create migrations that can be run - however I think we'll need to fix #2681869: Provide clean way to merge configuration into migration plugins to make this right.Comment #163
alexpott@benjy's changes in response to @catch's review look great. Given that I haven;t worked on this since the last rtbc - I'm happy to re-rtbc it.
Comment #164
vasi CreditAttribution: vasi at Evolving Web commented@benjy, I'm just doing that in a script now, to play with and understand the new system. I assume eventually migrate_tools will need to do something similar.
I should add that I really like the idea of using plugins instead of config entities in the abstract. I think it might come in really useful for i18n migrations, for example, having a TranslationDeriver that takes care of some or all of the dirty work. I just want to make sure that this patch ends up being the best it can be, not trying to make trouble.
Comment #165
mikeryan@vasi's issue was previously raised at https://www.drupal.org/node/2625696#comment-10863860 - yes, this is a concern for migrate_tools. Good to hear #2681869: Provide clean way to merge configuration into migration plugins should handle this.
Comment #166
xjmHooray, glad to see this RTBC again!
Tagging as a beta target; this issue is a priority for the 8.1.x beta phase.
Comment #167
xjmAlso.
Comment #168
alexpottRerolled - some clashes with the unused use statements...
Comment #169
catchOK. Committed/pushed to 8.2.x.
I have not yet cherry-picked to 8.1.x, after discussing with @alexpott:
- we can cherry-pick to 8.1.x whenever before tagging the second beta, but having this in 8.2.x helps to un-stack some patches
- there's at least one follow-up like the early return in test code it'd be good to have a green patch for and/or commit both to 8.2.x then cherry pick both to 8.1.x, couldn't decide how strongly I felt about that, so leaving at 8.2.x for now lets us get things going regardless.
Leaving RTBC against 8.1.x since we still might cherry-pick as-is.
Comment #170
Gábor HojtsyShould we publish the change record once the 8.1 merge happens? I assume that would be best for publicity.
Comment #171
catchYep makes sense
Cherry-picked to 8.1.x now - several follow-ups already in and don't want the branches to diverge too much yet.
Comment #174
matslats CreditAttribution: matslats as a volunteer commentedI spent the last day trying to migrate my content entity type from d7 using 8.1.0-beta1
I'm now stuck because my entityTypeId changed between versions and the d7_field migration cannot know that.
I will now try to resave the d7_field migration to add a process plugin to map the entityTypeId;
Also some dx feedback for you.
It was tough workflow editing my yml file because drupal stores it as config. I had to delete the config and reimport the yml file whenever I made a change.
Also once the migration had failed it didn't run again. I had to delete rows in the db or change the source_row_status column.
Comment #175
hussainwebPossible regression due to this change: #2691189: Rerunning a migration results in an error.
Comment #176
alexpott@hussainweb yeah - we're trying to remove this option in #2683421: Remove incremental and rollback options from the UI (and add them back when they are more stable)