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

Library schematic conflicts with itself when used with applyToSubtree #16082

Closed
CobusKruger opened this issue Nov 6, 2019 · 4 comments · Fixed by #19903
Closed

Library schematic conflicts with itself when used with applyToSubtree #16082

CobusKruger opened this issue Nov 6, 2019 · 4 comments · Fixed by #19903
Labels
area: devkit/schematics freq1: low Only reported by a handful of users who observe it rarely severity3: broken type: bug/fix
Milestone

Comments

@CobusKruger
Copy link

🐞 Bug report

Command (mark with an x)

- [ ] new
- [ ] build
- [ ] serve
- [ ] test
- [ ] e2e
- [ ] generate
- [ ] add
- [ ] update
- [ ] lint
- [ ] xi18n
- [ ] run
- [ ] config
- [ ] help
- [ ] version
- [ ] doc
- [X] schematics

Is this a regression?

Not that I'm aware of.

Description

I tried to create a schematic that would create an Anglar application and then create a library within that application, but the library schematic wouldn't run in the folder created by ng-new. That's explained in issue #16080, which is distinct from the issue I'm reporting here. It serves as background about why I needed to use applyToSubtree.

When I execute the library schematic within applyToSubtree, it seems to find the right folder and generates a list of files, but it then conflicts on the library's module file. To be clear, the library schematic creates a new file in a new folder and then fails with a merge conflict. I suspect that's because it calls schematics in turn to create a module, component and service.

Whichever way, there is no apparent way to get around this, because the merge happens within the library schematic itself and I'm not given the chance to supply a MergeStrategy.

Just because I know someone will ask: No, the file does not exist outside of the schematic and it was not created by the ng-new call.

🔬 Minimal Reproduction

You can find a minimal reproduction in this repo

Here's an abstract. I use this factory:

export function createProject(_options: any): Rule {
  return (_tree: Tree, _context: SchematicContext) => {
    return chain([
      externalSchematic('@schematics/angular', 'ng-new', optionsApp),
      applyToSubtree('NewAngularAppWithSubtree', [
        externalSchematic('@schematics/angular', 'library', optionsLib)
      ])
    ]);
  };
}

NewAngularAppWithSubtree is the path created by the ng-new call. A merge error then occurs on this file: /NewAngularAppWithSubtree/projects/new-lib/src/lib/new-lib.module.ts. Note that this file was created by the library schematic, not by ng-new.

🔥 Exception or Error


An error occured:
Error: A merge conflicted on path "/NewAngularAppWithSubtree/projects/new-lib/src/lib/new-lib.module.ts".
    at C:\Users\cobusk\AppData\Roaming\npm\node_modules\@angular-devkit\schematics-cli\node_modules\@angular-devkit\schematics\src\tree\host-tree.js:132:35
    at Array.forEach ()
    at HostTree.merge (C:\Users\cobusk\AppData\Roaming\npm\node_modules\@angular-devkit\schematics-cli\node_modules\@angular-devkit\schematics\src\tree\host-tree.js:121:23)
    at ScopedTree.merge (C:\dev\scratchpad\scaffolding-tests\AngularProjectMergeIssues\node_modules\@angular-devkit\schematics\src\tree\scoped.js:72:20)
    at MapSubscriber.project (C:\dev\scratchpad\scaffolding-tests\node_modules\@angular-devkit\schematics\src\rules\schematic.js:42:19)
    at MapSubscriber._next (C:\dev\scratchpad\scaffolding-tests\node_modules\rxjs\internal\operators\map.js:49:35)
    at MapSubscriber.Subscriber.next (C:\dev\scratchpad\scaffolding-tests\node_modules\rxjs\internal\Subscriber.js:66:18)
    at TapSubscriber._next (C:\dev\scratchpad\scaffolding-tests\node_modules\rxjs\internal\operators\tap.js:65:26)
    at TapSubscriber.Subscriber.next (C:\dev\scratchpad\scaffolding-tests\node_modules\rxjs\internal\Subscriber.js:66:18)
    at TakeLastSubscriber._complete (C:\dev\scratchpad\scaffolding-tests\node_modules\rxjs\internal\operators\takeLast.js:71:29)

🌍 Your Environment


     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
    

Angular CLI: 8.3.1
Node: 12.12.0
OS: win32 x64
Angular: undefined
...

Package                      Version
------------------------------------------------------
@angular-devkit/architect    0.803.1 (cli-only)
@angular-devkit/core         8.3.17
@angular-devkit/schematics   8.3.17
@schematics/angular          8.3.1 (cli-only)
@schematics/update           0.803.1 (cli-only)
rxjs                         6.4.0
typescript                   3.5.3
@ngbot ngbot bot added this to the needsTriage milestone Nov 7, 2019
@alan-agius4 alan-agius4 added freq1: low Only reported by a handful of users who observe it rarely type: bug/fix severity3: broken labels Nov 7, 2019
@ngbot ngbot bot modified the milestones: needsTriage, Backlog Nov 7, 2019
@pfeileon
Copy link

pfeileon commented Jun 17, 2020

I have the same issue when creating a custom project analog to this tutorial and then trying to create a lazy module with route.
The first issue is that when the module schematic calls the component schematic, the root path is wrong. This can be solved by adding an execution context {scope: [projectName]} and removing the [projectName] from the path.1 But then the CLI reports:

Error: A merge conflicted on path schematics route [pathToLazy.module.ts]

When I don't add a scope and instead hack getWorkspace(...) to add the project name to the path for the component schematic, only, there is no error and it works.

1 The module, pipe and service schematics all work fine, only directive and component are writing a root path (which is missing the project name) to the tree.

@d-koppenhagen
Copy link

Same issue here.

@pfeileon you wrote:

When I don't add a scope and instead hack getWorkspace(...) to add the project name to the path for the component schematic, only, there is no error and it works.

Would you mind to share your "hacked" getWorkspace() solution that works for you? I didn't manage to solve the issue locally by trying out lot's of things with pathes and handing over options etc.

@pfeileon
Copy link

pfeileon commented Nov 9, 2020

By "hack" I mean that I executed my schematics with the value hardcoded into getWorkspace() for investigation purposes. I don't have a solution other than copying the files unfortunately.

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Mar 4, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: devkit/schematics freq1: low Only reported by a handful of users who observe it rarely severity3: broken type: bug/fix
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants