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

[Feature] Impose constraints on the dependency graph via tags #81

Closed
photomoose opened this issue Aug 18, 2021 · 10 comments
Closed

[Feature] Impose constraints on the dependency graph via tags #81

photomoose opened this issue Aug 18, 2021 · 10 comments
Assignees
Labels

Comments

@photomoose
Copy link
Contributor

This functionality already exists but appears to be only implemented by linter plugins to ESLint or TSLint.

We have moved 50+ .NET projects over into a monorepo using nx-dotnet, but we now fear that it might become a monolith/ball of spaghetti if we cannot impose constraints on which apps can depend on which libraries.

Is there a solution for this?

@photomoose photomoose added enhancement New feature or request needs-triage This issue has yet to be looked over by a core team member labels Aug 18, 2021
@AgentEnder
Copy link
Member

AgentEnder commented Aug 18, 2021

Wow! I'm so glad to hear that you all have adopted nx-dotnet and only had a few small issues so far. If you have a chance, I'd love to hear more about how its went. Here is a discussion thread that would be great for that: #83

There is definitely a path to move forward on supporting nx-enforce-module-boundaries, but the existing rule does only support ESLint / TSLint. Better linting support is something I'd like to implement, but C# code analyzers run at build time rather than being in a separate lint step, which makes it a bit less comparable to something like eslint.

Anyways, the way to handle this would be writing a custom roslyn analyzer and either parsing eslintrc to get module boundaries configuration, or having a section for that in the nx-dotnet config file. I can try to work on this at some point next week, but I do not have personal experience with writing them yet. Should be fun to learn 😄.

The analyzer should be pretty simple, we wouldn't have to iterate over all of the C# files. Should just look something like

  1. Parse tags from nx.json
  2. Read boundaries either from eslintrc or nx-dotnet config
  3. Iterate over project files
    1. For each project reference, check if its an nx-dotnet project.
    2. Check tags, and if they are breaking a boundary
    3. If so, report error on that node in the csproj / vbproj / fsproj xml

If anyone on your team wants to try it out, they can feel free. I'll leave this as up-for-grabs until I take it, but if anyone wants it feel free to assign it to yourself.

@AgentEnder AgentEnder added help wanted Extra attention is needed scope: core and removed needs-triage This issue has yet to be looked over by a core team member labels Aug 18, 2021
@AgentEnder
Copy link
Member

@photomoose A roslyn analyzer would give feedback during regular development in the ide, but would a prebuild msbuild task be acceptable for you?

An msbuild task would allow us to reuse existing utilities as we could write it in node.

@photomoose
Copy link
Contributor Author

@AgentEnder Sure, an msbuild task will probably suffice - we're just looking for something to fail the build essentially - not too fussed about it being reported in the IDE at the moment (although that might be a nice to have).

I'll document our experiences so far in #83 shortly... but at the moment, things are looking promising. I've discovered a few minor issues which I'll either fix or raise issues accordingly.

@AgentEnder AgentEnder removed the help wanted Extra attention is needed label Aug 19, 2021
@AgentEnder AgentEnder self-assigned this Aug 19, 2021
github-actions bot pushed a commit that referenced this issue Aug 20, 2021
# [1.2.0](v1.1.4...v1.2.0) (2021-08-20)

### Features

* **core:** [#81](#81) support for nx-enforce-module-boundaries ([3fc92fd](3fc92fd))
* **core:** ability to load module boundaries from nx-dotnet config ([2618b5d](2618b5d))

Aug 20, 2021, 1:55 AM
@AgentEnder
Copy link
Member

This was fixed in #85, and should be available in v1.2.0

@photomoose
Copy link
Contributor Author

@AgentEnder amazing, you implemented this pretty damn quickly, many thanks! I'll give it a test and see how it works out for us, I'll let you know the end result.

Just a quick question - I notice the PR contains a migration to update all the proj files with the MSBuild task - how is this migration actually invoked? I've tried running nx migrate @nx-dotnet/core, which updates the package to
v1.2.0, but I do not see any changes to the proj files.

@AgentEnder
Copy link
Member

Did it put the migration into migrations.json? You may still need to run nx migrate --run-migrations

@photomoose
Copy link
Contributor Author

It didn't create the migrations.json file the first time I ran it - however I am putting this down to me messing up the upgrade of the package with npm somehow.....

After discarding my local changes and reverting to v1.1.4, it correctly generated the migrations.json file, which once applied, has successfully added the build targets in all the proj files. Very nice indeed....I'll get tagging the projects tonight and see how it works. Thanks again :-)

@photomoose
Copy link
Contributor Author

Probably a non-issue, but if you don't have either an eslint config file or the moduleBoundaries key in the .nx-dotnet.rc.json file, then the build outputs some noisy error:

> nx run common-identity:build
Executing Command: dotnet build libs/common/identity/Contingent.Common.Identity.csproj --output dist/libs/common/identity --configuration Debug --verbosity minimal
Microsoft (R) Build Engine version 16.8.0+126527ff1 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.

  Determining projects to restore...
  All projects are up-to-date for restore.
  Contingent.Common.Identity -> /Users/tom.davis/Contingent/services-dotnet/dist/libs/common/identity/Contingent.Common.Identity.dll
  Checking module boundaries for common-identity
  (node:42964) UnhandledPromiseRejectionWarning: Error: No ESLint configuration found in /Users/tom.davis/Contingent/services-dotnet/libs/common/identity.
      at CascadingConfigArrayFactory._finalizeConfigArray (/Users/tom.davis/Contingent/services-dotnet/node_modules/@eslint/eslintrc/lib/cascading-config-array-factory.js:508:19)
      at CascadingConfigArrayFactory.getConfigArrayForFile (/Users/tom.davis/Contingent/services-dotnet/node_modules/@eslint/eslintrc/lib/cascading-config-array-factory.js:299:21)
      at CLIEngine.getConfigForFile (/Users/tom.davis/Contingent/services-dotnet/node_modules/eslint/lib/cli-engine/cli-engine.js:953:14)
      at ESLint.calculateConfigForFile (/Users/tom.davis/Contingent/services-dotnet/node_modules/eslint/lib/eslint/eslint.js:674:26)
      at /Users/tom.davis/Contingent/services-dotnet/node_modules/@nx-dotnet/core/src/tasks/check-module-boundaries.js:48:56
      at Generator.next (<anonymous>)
      at /Users/tom.davis/Contingent/services-dotnet/node_modules/tslib/tslib.js:117:75
      at new Promise (<anonymous>)
      at Object.__awaiter (/Users/tom.davis/Contingent/services-dotnet/node_modules/tslib/tslib.js:113:16)
      at loadModuleBoundaries (/Users/tom.davis/Contingent/services-dotnet/node_modules/@nx-dotnet/core/src/tasks/check-module-boundaries.js:45:20)
  (Use `node --trace-warnings ...` to show where the warning was created)
  (node:42964) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
  (node:42964) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Putting an empty "moduleBoundaries: []" in .nx-dotnet.rc.json squashes this error.

@AgentEnder
Copy link
Member

AgentEnder commented Aug 20, 2021

Ah, thats a good point. I'll add a check that the eslint is configured before trying to do the dynamic import.

@github-actions
Copy link
Contributor

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 25, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants