Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce custom ESLint rules to apply and enforce new themed component selector convention #2865

Merged
merged 37 commits into from
Apr 30, 2024

Conversation

ybnd
Copy link
Member

@ybnd ybnd commented Mar 14, 2024

References

Add references/links to any related issues or PRs. These may include:

Description

This PR introduces custom ESLint plugins as a means of automatically migrating to the new themed component selector convention proposed in #2845, as well as enforcing this convention moving forward.

Furthermore, these plugins can be leveraged in future PRs to create more rules for DSpace Angular in particular.

Note that this PR also enables linting for our Cypress tests, since they are affected by the selector change (most of the changes there are indentation/import order).

Instructions for Reviewers

  • The first commit of this PR includes the bulk of the new rules, enough to cover the majority of cases
    • It feels right to bundle these plugins in the project itself, since they are tightly coupled to DSpace Angular.
      • Do you agree? Any comments on the structure?
    • The new plugins do not add more than a few seconds to the total linting time.
    • Please observe the lint output in the GitHub build logs, or locally if you check out this commit.
      Are the messages sufficiently clear?
  • The "auto-migrate" commit includes only the results of yarn lint --fix. The manual interventions can be found in the subsequent commits
    • These commits can serve as an example of what downstream forks will have to do to migrate to the new convention (but likely a lot less than was necessary in this PR)
    • Is this reasonable? Do we need more detailed instructions?
  • The app should remain functionally the same
    • Run locally to confirm
    • Check a few themeable components to confirm that
      • The new convention is correctly reflected in the DOM
      • Everything still renders exactly as before
    • Switch between the dspace and custom themes
  • If you're using Windows, I'd greatly appreciate if you check whether all new yarn scripts work there as well (they have already been tested on MacOS and Linux).

Instructions for fork developers

After upgrading your fork to DSpace 8.0, run yarn lint --quiet --fix

  • This should automatically migrate any custom themeable/themed components in your project
  • Build/test/deploy your project and verify that everything still works
    • If there were major problems with the migration, they will come up as compilation errors. These can include
      • Out-of-sync inputs between the base themeable component and its ThemedComponent wrapper
      • ...
    • Please open an issue on GitHub if the cause of the problem is not clear

Future work

I've already worked on similar ESLint rules in a separate project; if we decide to merge this PR it may be useful to port them to the "internal" lint plugin:

  • Enforce correct theme declarations in entry component decorators such as @listableObjectComponent
  • Enforce globally unique entry component decorators (to avoid silent overrides)
  • Enforce import aliases (e.g. of as observableOf)

And moving forward there are many other DSpace-isms that we could write rules for

  • Ensure that the inputs and outputs of ThemedComponent wrappers match the base component exactly
  • Ensure that component overrides in themes do not introduce new inputs or outputs
  • ...

Checklist

This checklist provides a reminder of what we are going to look for when reviewing your PR. You need not complete this checklist prior to creating your PR (draft PRs are always welcome). If you are unsure about an item in the checklist, don't hesitate to ask. We're here to help!

  • My PR is small in size (e.g. less than 1,000 lines of code, not including comments & specs/tests), or I have provided reasons as to why that's not possible.
  • My PR passes ESLint validation using yarn lint
  • My PR doesn't introduce circular dependencies (verified via yarn check-circ-deps)
  • My PR includes TypeDoc comments for all new (or modified) public methods and classes. It also includes TypeDoc for large or complex private methods.
  • My PR passes all specs/tests and includes new/updated specs or tests based on the Code Testing Guide.
  • If my PR includes new libraries/dependencies (in package.json), I've made sure their licenses align with the DSpace BSD License based on the Licensing of Contributions documentation.
  • If my PR includes new features or configurations, I've provided basic technical documentation in the PR itself.
  • If my PR fixes an issue ticket, I've linked them together.

@ybnd ybnd added needs discussion testing framework Related specifically to Unit or Integration (e2e) Tests labels Mar 14, 2024
@ybnd ybnd force-pushed the poc-eslint-plugin-autofix-selectors branch 2 times, most recently from 82b630a to 047528d Compare March 14, 2024 11:39
@ybnd ybnd marked this pull request as ready for review March 15, 2024 13:21
@ybnd
Copy link
Member Author

ybnd commented Mar 15, 2024

Still some e2e failures, but I'm pretty sure that those tests were already flaky

@ybnd ybnd force-pushed the poc-eslint-plugin-autofix-selectors branch from ccbd5de to 0876691 Compare March 15, 2024 15:39
Copy link

Hi @ybnd,
Conflicts have been detected against the base branch.
Please resolve these conflicts as soon as you can. Thanks!

@ybnd
Copy link
Member Author

ybnd commented Mar 20, 2024

Note: by far most of the conflicts will be due to the automatic lint fixes, so I'll address them in one go when the PR is approved.

Probably best to drop 3753b29, d15327c, db7a371 and re-do everything at the end of the branch for clarity.

ybnd added 8 commits March 21, 2024 10:11
The following cases are covered:
- ThemedComponent wrapper selectors must not start with ds-themed-
- Base component selectors must start with ds-base-
- Themed component selectors must start with ds-themed-
- The ThemedComponent wrapper must always be used in HTML
- The ThemedComponent wrapper must be used in TypeScript _where appropriate_:
  - Required
    - Explicit usages (e.g. modal instantiation, routing modules, ...)
    - By.css selector queries (in order to align with the HTML rule)
  - Unchecked
    - Non-routing modules (to ensure the components can be declared)
    - ViewChild hooks (since they need to attach to the underlying component)

All rules work with --fix to automatically migrate to the new convention
This covers most of the codebase, but minor manual adjustment are needed afterwards
@tdonohue tdonohue requested review from tdonohue and atarix83 March 21, 2024 15:35
ybnd added 5 commits March 28, 2024 18:33
- ThemedComponent wrappers should always import their base component. This ensures that it's always enough to only import the wrapper when we use it.
- This implies that all themeable components must be standalone

→ added rules to enforce this
→ updated usage rule to improve declaration/import handling
Fixes compile-time errors due to out-of-sync inputs and outputs between ThemedConfigurationSearchPageComponent and SearchComponent

(note that this is was an existing problem in the source code that flew under the radar until we flipped the selector convention!)
The automatic migration made it so HTML always uses the `Themed*` component, and it must therefore be imported in all standalone components that use it.
Afterwards, many unit tests fail because the removed imports no longer match up (can't inject `ThemeService`).

While we could try to support this as part of the automatic migration, there are too many edge cases for this to be consistent.
`Themed*` components should be used in the actual codebase to ensure we retain theme support.
However, in unit tests these components won't work without a fully-functional `ThemeService` & `Store`.

For this reason, the lint plugin allows `ds-base-*` selectors in unit test templates.
@ybnd ybnd force-pushed the poc-eslint-plugin-autofix-selectors branch from 0876691 to a6e0930 Compare March 28, 2024 17:52
@ybnd
Copy link
Member Author

ybnd commented Apr 24, 2024

@tdonohue @atarix83 I'm not super familiar with the Docker setup, but it seems like it involves a yarn install with only package.json & yarn.json, so it's failing during the new postinstall script.

Added a condition to check whether the lint plugin sources are present before trying to build, let's see if that's enough 🤞

Edit: @artlowel pointed out that that wouldn't be cross-platform, so I changed it to "skip if failed" so we can avoid introducing a new Node dependency just for this one tiny thing.

There is no cross-platform way to check if the file/directory exists that doesn't depend on adding another NodeJS dependency.
This "skip if failed" approach is more noisy, but it should work everywhere.
Copy link
Member

@artlowel artlowel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @ybnd that looks good!

@tdonohue it would be good if you could still run a sanity check to verify the build works as it should on windows, given the changes in 728b561

package.json Outdated Show resolved Hide resolved
Copy link
Member

@tdonohue tdonohue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ybnd : I've tested this today in production mode (yarn build:prod; yarn serve:ssr) on Windows 11. While it works for the dspace theme, the custom theme is broken. Here's what I see

custom-theme

There are a number of issues that are visible. The header no longer works, no ability to login or browse the site, much of the homepage content no longer displays, etc. Individual item pages are no better.

This doesn't appear to be a caching issue on my end, as after checkout of this PR I ran the following:

yarn clean
yarn install
yarn build:prod
yarn serve:ssr

I also attempted a hard reload in the browser in case this is a CSS issue.

I'll note that with the custom theme enabled, there are SSR errors that occur such as this one:

ERROR TypeError: Cannot read properties of undefined (reading 'onDestroy')
    at Object.ɵɵpipe (C:\dspace-angular\dist\server\main.js:1:4326830)
    at template (C:\dspace-angular\dist\server\1210.js:1:3854)
    at executeTemplate (C:\dspace-angular\dist\server\main.js:1:4182823)
    at renderView (C:\dspace-angular\dist\server\main.js:1:4198373)
    at renderComponent (C:\dspace-angular\dist\server\main.js:1:4198106)
    at renderChildComponents (C:\dspace-angular\dist\server\main.js:1:4198794)
    at renderView (C:\dspace-angular\dist\server\main.js:1:4198836)
    at ComponentFactory.create (C:\dspace-angular\dist\server\main.js:1:4235830)
    at R3ViewContainerRef.createComponent (C:\dspace-angular\dist\server\main.js:1:4239623)
    at Object.next (C:\dspace-angular\dist\server\main.js:1:2265629)

Finally, not all of the new yarn commands are working for me on Windows. Here's what works and what doesn't:

  • yarn build:lint - Succeeds
  • yarn test:lint - FAILS. I get two errors in the dspace-angular\lint\test\fixture\src\test.ts file.
    1) TypeScript rules themed-component-usages invalid disallow direct usages of base class
    Message:
    Error: Can't infer project-absolute TS/resource path from: C:\dspace-angular\lint\test\fixture\src\test.ts
    Occurred while linting C:\dspace-angular\lint\test\fixture\src\test.ts:2
    Rule: "themed-component-usages"
    
    2) TypeScript rules themed-component-usages invalid disallow direct usages of base class, keep other imports
    Message:
    Error: Can't infer project-absolute TS/resource path from: C:\dspace-angular\lint\test\fixture\src\test.ts
    Occurred while linting C:\dspace-angular\lint\test\fixture\src\test.ts:2
    Rule: "themed-component-usages"
    
  • yarn test:lint:nobuild - FAILS with the same two errors (obviously)
  • yarn lint - FAILS. I get 97 lint errors in the custom theme. All of them say something like "Unthemed version of themable component should have a selector starting with 'ds-base-'". Maybe this is why the "custom" theme is not working for me?
  • yarn lint:nobuild - FAILS (same as yarn lint obviously)
  • yarn lint-fix - Succeeds. It fixes all 97 errors above, but changes 97 files in the "custom" theme in the same way. Here's an example of the diff change (changed ds-themed-admin-sidebar to ds-base-themed-admin-sidebar):
    --- a/src/themes/custom/app/admin/admin-sidebar/admin-sidebar.component.ts
    +++ b/src/themes/custom/app/admin/admin-sidebar/admin-sidebar.component.ts
    @@ -15,7 +15,7 @@ import { AdminSidebarComponent as BaseComponent } from 
    '../../../../../app/admin
      * Component representing the admin sidebar
      */
     @Component({
    -  selector: 'ds-themed-admin-sidebar',
    +  selector: 'ds-base-themed-admin-sidebar'
    
  • yarn docs:lint - Succeeds, but changes all line endings in the /docs/lint/** subdirectories to CRLF instead of LF. (This is not a serious issue...it's something we could live with if we had to)

While the overall code looks reasonable to me, this doesn't seem to be fully functional (at least not on Windows).

@tdonohue
Copy link
Member

tdonohue commented Apr 24, 2024

@ybnd : Apologies, I've since discovered that some of the bugs that I've run into are not the cause of this PR. The custom theme doesn't work on main either, so I logged a bug ticket #2977

Unfortunately though, that makes it difficult to fully test this PR until that ticket is fixed. In the meantime though, all the yarn script failures on Windows obviously seem specific to this PR.

@ybnd
Copy link
Member Author

ybnd commented Apr 25, 2024

@tdonohue I've addressed the issues with the new yarn scripts on Windows, so this should be ready to review again once #2977 is resolved

Copy link

Hi @ybnd,
Conflicts have been detected against the base branch.
Please resolve these conflicts as soon as you can. Thanks!

@tdonohue
Copy link
Member

@ybnd : This has minor conflicts caused by the fix to the custom theme: #2984 Once those conflicts are resolved, I should be able to test this again (hopefully on/around Monday)

ybnd added 2 commits April 30, 2024 10:47
This is part of the themed-component-usages rule; Themed* components already import the base component, we don't need to import both anymore.
You'll see that all of these changes are also reflected in the base component.

Double-checked and this doesn't compromise the fixes from DSpace#2984
@ybnd
Copy link
Member Author

ybnd commented Apr 30, 2024

@tdonohue couldn't make Monday, hopefully today is still ok timing-wise.

Copy link
Member

@tdonohue tdonohue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Thanks @ybnd ! I've retested this today and all the yarn scripts now work on Windows. I've also verified that theming is working as normal & I can still do things like configure a different theme per community/collection and the custom and dspace themes both work.

I'll merge this, but I'm also flagging it as needs documentation. I think this needs to have basic docs created in the Upgrading DSpace documentation as it seems like sites should now run yarn lint --fix whenever they upgrade? I may need your help with updating these docs so that they are accurate/complete. But if you'd rather provide the details on this PR, then I can copy them into the docs.

@tdonohue tdonohue added needs documentation PR is missing documentation. All new features and config changes require documentation. improvement and removed needs discussion labels Apr 30, 2024
@tdonohue tdonohue added this to the 8.0 milestone Apr 30, 2024
@tdonohue tdonohue merged commit 0fa5d18 into DSpace:main Apr 30, 2024
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
improvement needs documentation PR is missing documentation. All new features and config changes require documentation. testing framework Related specifically to Unit or Integration (e2e) Tests themes
Projects
No open projects
Status: ✅ Done
Development

Successfully merging this pull request may close these issues.

Replace original selector when making a component themeable
4 participants