Problem/Motivation
locale.compare.inc has a bunch of intertwined logic for tracking translations and batches.
Let's start organizing the non batch related code here.
Proposed resolution
- Move the logic from
locale.compare.incinto a new serviceLocaleProjectRepository. - Move the two project check methods to LocaleProjectChecker
- Create new LocaleTranslatableProject value object
- Deprecate all functions unrelated to batch from
locale.compare.inc. - Deprecate LocaleProjectStorageInterface and services and move relevant methods to the new LocaleProjectRepository service
Remaining tasks
Update the CRs if necessary after merging this:
- LocaleSource https://drupal.org/node/3569330
- LocaleFetch https://www.drupal.org/node/3572345
- LocaleFileManager https://www.drupal.org/node/3577675
Follow up:
#3589049: Explore avoiding buildProjects in the TranslationStatusForm
#1842380: Convert $source object to a LocaleTranslationSource class
#3589344: Remove the ability to have enabled/disabled projects in the locale project repository
User interface changes
N/A
API changes
- New service
LocaleProjectRepository - New service
LocaleProjectChecker - Deprecated functions:
locale_translation_flush_projects()locale_translation_build_projects()locale_translation_project_list()_locale_translation_prepare_project_list()locale_translation_default_translation_server()locale_translation_check_projects()
locale_translation_check_projects_local()
- locale.project
- LocaleProjectStorageInterface
- LocaleProjectStorage
The relevant methods from the deprecated service have been moved to LocaleProjectRepository, see the CR for full details.
There is a new LocaleTranslateableProject value object.
Data model changes
N/A
Release notes snippet
N/A
| Comment | File | Size | Author |
|---|
Issue fork drupal-3037031
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
- 3037031-local-compare-11x
changes, plain diff MR !15726
- 3037031-locale-comparev2
changes, plain diff MR !15655
- 3037031-locale-compare-same-project-source
changes, plain diff MR !15696
- 3037031-pp-1-convert-locale.compare.inc
changes, plain diff MR !15500
- 3037031-locale-compareNoGetProjects
changes, plain diff MR !15690
- 3037031-locale-compare-combined
changes, plain diff MR !15654
Comments
Comment #2
claudiu.cristeaComment #3
claudiu.cristeaWhile working on this is discovered #3037042: Convert LocaleUpdateTest::testUpdateProjects() to a kernel test.
Comment #4
claudiu.cristeaComment #5
claudiu.cristeaOMG, locale is Hell!
This is just a working patch. Far away to be finished.
Comment #7
claudiu.cristeaNarrowing failures.
Comment #9
claudiu.cristea[removed]
Comment #10
claudiu.cristeaFixed failures, coding standards. Added deprecation test.
Comment #12
claudiu.cristeadrupal_static_reset('locale_translation_project_list'). Add test.Comment #15
kishor_kolekar commented#12 Patch Re-rolled for 9.1.x
Please review
Comment #16
daffie commented@kishor_kolekar: The testbot is not happy with your reroll. At least the deprecation messages need to be updated to deprecate in 9.1 and removed in 10.0.
Comment #17
hardik_patel_12 commentedUpdating deprecate message and re-rolled the patch.
Comment #18
quietone commented@Hardik_Patel_12, Thanks for working on this issue. The types of issues being worked on by the Bug Smash Initiative are listed on the Bug Smash Initiative page and does not include Tasks. So, I am removing the tag.
Comment #19
hardik_patel_12 commented@quietone , sure will keep in mind this. Thanks for your suggestion.
Comment #20
kishor_kolekar commentedThank you @daffie for ur suggestion.
Thanks @Hardik_Patel_12 for working on it.
Comment #21
daffie commentedTestbot still not happy.
Comment #22
hardik_patel_12 commentedSolving failed test cases. Kindly follow a new patch.
Comment #23
hardik_patel_12 commentedComment #25
msutharsComment #26
msutharsFixed the coding standard and testcase issues.
Comment #27
msutharsComment #28
msutharsUpdated patch.
Comment #31
sutharsan commentedPatch re-rolled
Comment #32
claudiu.cristeaThe Drupal version should be updated here and also in change record. Also the message pattern should follow https://www.drupal.org/project/coding_standards/issues/3024461.
Needs a dot at the end.
Comment #33
sutharsan commentedBoth above comments are addressed.
Also added missing 'array' type hints in
LocaleProjectStatusInterface::remoteTranslationStatusOperationsandLocaleProjectStatus:Comment #34
sutharsan commentedSpell check fixes.
Comment #36
sutharsan commentedTrying to fix the deprecation tests.
I could not find a way to cover the deprecation error triggered at the top of the .inc file. I decided to remove this trigger althogether. Not a nice approach, but the best I could come up with.
Comment #37
andypostQuickly skimed a pacth and last interdiff, will do deeper review later tonight
not sure this line need to be removed, as this file no longer loaded... contrib or custom code using to load it should fail
Comment #38
sutharsan commentedRe #37, I removed this line because I could not find a way to get the test working _with_ this line. As I tried to explain in #36.
Further I searched for other other .inc files which got deprecated to look for a pattern. #2044435: Convert pager.inc to a service deprecate pager.inc, it did not use a deprecation message at file level. I found no deprecated .inc files in core. Further the existing documentation standard on
@deprectatedonly mentions function, method, class. The coding standards issue mentioned in #32 extends this list further (below), but does not mention deprecation of files. Therefore I propose to remove the@deprectatedat file level and only use it for functions.Comment #39
sutharsan commentedThis issue converts _all_ functions in locale.compare.inc into one service where each function gets a method. In the current code of Locale module I found the
LocaleConfigManagerservice which (a.o.) is called by batch functions in locale.bulk.inc.This made me wonder whether it is proper architecture to include these batch functions into a service like
LocaleConfigManagerandLocaleProjectStatus(this issue). I am leaning towards separating the batch function from the functions that do the "work". In other words to move the batch building and batch operation/finish functions out of this patch.Comment #40
berdirAFAIK, batch callbacks can't be on services yet, only functions or static methods. Closest I managed is a batch function "dispatcher" than then calls the service. See _simplenews_batch_dispatcher() in simplenews.module.
Comment #41
sutharsan commented@Berdir, Thanks for the tip,
_simplenews_batch_dispatcher()is a clever way to call a service method from where only call_user_function_array is used by Drupal's batch API.Let me break down the batch related parts of batch code: The Batch builder (which returns an array of batch title, operations, finished, etc., the batch definition as required by batch_set()), Batch operation callback (called by the batch API, handles batch administration and calls the Worker) and the Worker (which performs the actual task, but is not batch agnostic).
In my opinion the Worker should not be aware of the batch. Making the worker batch aware makes unit testing and re-use in other contexts harder. I did not check how the current procedural code does or does not mix batch and worker, but I'm painting my ideal picture here. A service is probably the first choice for the worker, and the service may combine multiple workers (called by multiple batch operations).
The question I'm raising here is whether we should (not) combine the Batch operation callback(s) and Batch builder into this Worker service. Worker, operation callbacks and builder in their own methods of course, but combined in one class. I did not find an OO pattern in core for Batch builder and Batch operation callbacks. I only found them in procedural code. As I mentioned above I lean towards _not_ combining them into the worker, but keep them separate (for re-use and unit testing). When choosing for separation, we can keep them procedural for now. But I 'd rather find an OO pattern for this too.
This choice is not only relevant for this issue, but for all of Locale module's .inc files which are subject to refactoring in of #3215707: [META] Modernize Locale module.
Comment #42
andypost@Sutharsan The batch builder already in core https://www.drupal.org/node/2875389 but its adoption a bit staled #2875151: [META] Implement Batch API as a service
There's even #1797526: Make batch a wrapper around the queue system but I'm not sure it has enough chances to get in fast, OTOH locale could be first case to use it
Comment #43
gábor hojtsyIMHO we should separate if the worker part needs to be reusable, eg. used in multiple batches or by contrib, or should be overridden as for what the worker does vs not how the batch is built (separation of concerns). Testing may be another good reason indeed that I did not think of before.
Comment #44
daffie commentedA couple of nitpicks about the new interface:
Could we add ": void" to indicate that the method does not return anything.
Could we add ": array" to indicate that the method returns an array.
The parameter is optional. Could we add "(optional)" to the parameter documentation.
Comment #48
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #51
claudiu.cristeaComment #52
nicxvan commented#3577671: Modernize locale file handling
Comment #53
nicxvan commentedComment #54
nicxvan commentedI'm going to actually start fresh, the patch does not apply across 13 files and we've changed process, I'll review the patch for locations that functions landed.
Comment #55
nicxvan commentedMade it about halfway, haven't run CS so I won't do a MR since I know it will fail, but gotta take a break.
Comment #56
nicxvan commentedComment #58
nicxvan commentedComment #59
claudiu.cristeaAdding #1842380: Convert $source object to a LocaleTranslationSource class as related
Comment #60
nicxvan commentedThank you, I'll take that under consideration, but I think we don't want all of that overhead, another value object should be enough.
We do have to figure out how to incorporate projectInfo since this also uses that.
Comment #61
claudiu.cristeaWorking on this. It's still far for completion
Comment #62
nicxvan commentedI added a couple of fixes and some comments, I'd like to chat about scope and what you think about the changes in LocaleSource.
One nice thing is that we added LocaleSource in 11.4 so if we need to change something as long as we get it in before 11.4 we can change it a bit.
Comment #67
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #68
nicxvan commentedOk, let's see how this goes.
I converted the object in
LocaleSourceto use theLocaleTranslatableProjectobject.There are some properties stored on that object that look like just LocaleFile properties but are used elsewhere.
type is overloaded so I created a new property fileType to track.
I created the properties on the class so we could just set them and see what we should do. We could maybe keep them short term, but I am not sure.
There is a fairly complex conflation of
LocaleTranslatableProjectandLocaleFilebetweenLocaleSource,locale_translation_update_file_historyandlocale_translation_status_save.I also deprecated
LocaleProjectStorageandLocaleProjectStorageInterface.Most of the failures are due to using a deprecated service, but I think it's the alias:
Comment #69
nicxvan commentedDown to the dreaded functional failures:
Fail locally:
Drupal\FunctionalTests\Installer\InstallerTranslation
Drupal\Tests\search_help\Functional\HelpTopicSearch
Drupal\Tests\locale\Functional\LocaleConfigTranslationImport
Drupal\Tests\locale\Functional\LocaleUpdateCron
Drupal\FunctionalTests\Installer\InstallerExistingConfigSyncDirectoryMultilingual
Drupal\Tests\help\Functional\HelpTopicTranslation
Drupal\FunctionalTests\Installer\InstallerTranslationMultipleLanguageForeign
Drupal\FunctionalTests\Installer\InstallerTranslationMultipleLanguageNonInteractive
Drupal\Tests\locale\Functional\LocaleUpdate
Drupal\FunctionalTests\Installer\InstallerTranslationMultipleLanguageKeepEnglish
Drupal\FunctionalTests\Installer\InstallerTranslationMultipleLanguage
Drupal\FunctionalTests\Installer\InstallerTranslationNonStandardFilenames
Drupal\Tests\locale\Functional\LocaleTranslationChangeProjectVersion
Passes locally:
Drupal\Tests\locale\Functional\LocaleUpdateInterface
Comment #70
nicxvan commentedDown to just a few, a bunch of the tests failed due to conflated type and file type properties, we probably need to truly clean that up.
I also removed readonly for now from the properties.
Drupal\Tests\locale\Functional\LocaleUpdate
Drupal\FunctionalTests\Installer\InstallerExistingConfigSyncDirectoryMultilingual
Drupal\Tests\locale\Functional\LocaleUpdateInterface
Comment #71
nicxvan commentedOk I got this green, this is still kind of rough, but it's ready for a round of reviews.
I imagine we want to try to better decide what to do about the repeated properties on
LocaleTranslatableProject. Also a cleaner way to differentiate between the type onLocaleTranslatableProjectandLocaleFile(They each have type, but the legacy code seemingly randomly overwrote the project type to the file type, I added a new fileType property to track, but it lead to much confusion.I also updated the CR.
We also have to not trigger deprecation for LocaleProjectStorageInterface or add the deprecated key to the LocaleProjectStorageInterface service alias due to: #3588483: Deprecating services that are autowired and autoconfigured doesn't quite work
I updated a bunch of other services to help fix some circular dependencies in
LocaleFileManagerandLocaleSource. I think these changes make this issue crucial to get into 11.4 if possible since those classes are not released yet and we'll avoid double deprecations.Comment #73
nicxvan commentedComment #74
nicxvan commentedComment #76
nicxvan commentedOk I addressed almost all of the super straightforward stuff on the current MR, I updated the CR with those changes, but will need a new pass to make sure I didn't forget something especially if we go to the new MR.
For the getProject, get, getMultiple etc I created a new MR since it's a behavior change, I think it's good minus a bit of messiness changing getAll behavior and needing to check if we need multiple or all. All of the get calls now populate the cache properly so a few tests don't work, it's also a new object, so the assert same won't work, I deleted some tests there and commented out two that we may want to discuss. Honestly this is probably better, why do we want to have out of sync projects and cache deleting a project?
I think the two big remaining questions not addressed here fully:
1. Do I go back to type and just document it can be extension type or file location type?
2. Do we try to reuse the translatable project passed into LocaleSource or do we need a psuedo clone.
Comment #82
nicxvan commentedComment #83
nicxvan commentedComment #84
nicxvan commentedComment #85
nicxvan commentedComment #86
nicxvan commentedThis is starting to really shape up!
I addressed the most recent round of feedback and updated a few things too.
This is ready again! I took a look at the IS and CR with the most recent changes.
Comment #87
nicxvan commentedComment #88
berdirWe discussed the $source vs project stuff in LocaleSource and I proposed some changes to that, that essentially restore it almost exactly to HEAD and no longer merges those two things together. It's a weird split, they are overlapping and cloned from each other, but each has their own distinct properties and behaviors and I think we should not merge them. This allows us to remove several properties from LocaleTranslatableProject that were only used after being converted to a source. This also solves the type property conflict. Discussed that extensively in Slack.
I will update the old follow-up #1842380: Convert $source object to a LocaleTranslationSource class to add a type for $source, we could revive that for that in a follow-up.
That is and will likely remain my only direct code contribution to this MR, I think I'm still OK RTBC'ing this after it this been cross-reviewed.
Comment #89
nicxvan commentedWe discussed the changes in the previous comment before @berdir pushed them, I also reviewed the commits directly and the flow after.
It's mainly scaling back some of the changes made here that really should be done in a follow up, @berdir already identified the follow up.
I'll sign off on his changes, I think this is ready for review again, I've addressed all feedback!
Comment #90
berdirRefactoring the locale module is really a challenge. There is so much code, complex value objects that are just so slightly different ($source vs $project, which this tried to unify but we undid that again), so many features and functions. The project storage is essentially a cache but comes with an extensive storage/new repository service that we slimmed down but still does a a lot. Sometimes the data is completely deleted and rebuilt (clicking the check manually button on the reports page), sometimes removed/uninstalled projects are just disabled, there is the sorting which I don't know what it's really used for and so many other things.
We tried our best to find a middle ground between refactoring, using typed value objects, reducing the API service but also still somewhat limiting the scope here to be able to finish this. We have a number of follow-ups and I just filled #3589344: Remove the ability to have enabled/disabled projects in the locale project repository for the status stuff.
This isn't perfect, but I think it's a reasonable improvement. and while the diff stats don't show that reduction in complexity/API surface (+ 828 − 320), that is mostly due to the old code only being deprecated. Once we can remove all the code in locale.compare and the old storage service, this should be roughly even again.
Added one more comment and comment suggestion on the MR, but I think that's not holding up an RTBC.
Comment #91
nicxvan commentedThank you! I updated the two comments after confirming your question.
As you mentioned we still have a fair bit to do, but this is pretty good progress I think.
We have the two follow ups you created and the plan for .module elimination (all of the batch functions are in the next issue, but based on how these have gone that might be ambitious).
Comment #92
nicxvan commentedComment #93
catchThis all looks good to me, but one small question on the MR.
Comment #95
catchCommitted/pushed to main, thanks!
Will need an 11.x backport MR, looks like services.yml and a test so hopefully not too bad.
Comment #98
nicxvan commentedThe backport should be ready.
The additional +2 are from needing autowire: true on the two new services.
The additional -8 are from the deleted test difference (one of the reasons there wasn't a clean backport)
The reasons we needed a backport:
Services autowiring
locale.translation.inc a use statement needed to be added
bootstrap.inc the drupal_static_reset changes
I compared the main commit with the backport and the changes are all the same.
Comment #101
catchCommitted/pushed to 11.x, thanks!
Comment #103
nicxvan commentedI updated the previous CR.
The only one that changed was https://www.drupal.org/node/3569330 for the
locale_translation_get_projectsdeprecation.Comment #104
nicxvan commentedComment #105
quietone commentedI published the recently reviewed change record.