Skip to content

refactor: ensure paths are safely passed around in ng-update #19354

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

Merged

Conversation

devversion
Copy link
Member

@devversion devversion commented May 14, 2020

Schematics using the TypeScript compiler API have a significant issue
with paths. The problem is that the TypeScript compiler API intends to
rely fully on absolute paths, while ng-update and the devkit tree intend
to rely on project-scoped/relative paths.

This is problematic as it is straightforward to mix paths up, leading to
unexpected errors. For example, computing a relative path between a devkit
path and an absolute disk path results in a non-existent path.

To fix this ambiguity, we improve type safety of paths by using branded
primitives such as the @angular-devkit/core Path or an even more
strict type called WorkspacePath. A normal string is considered an
unresolved path and cannot be assigned to a WorkspacePath. Similarly a
WorkspacePath cannot be assigned to a string. This ensures that
resolved paths are not accidentally mixed with unresolved paths, and
that we can safely pass around unresolved and resolved paths without
loss of their semantics.

This fixes a case (and potentially more) where a devkit path and an absolute disk
path result in an incorrectly resolved resource. In CLI apps it's possible to reference
resources through absolute project-scoped paths. e.g. /src/app/app.component.html. This has been fixed, and tests have been added (this might be the fix for #19354)

Note: Long-term it would be ideal to implement a TypeScript compiler host that only deals with resolved workspace paths, but this is not possible yet as implementing TypeScript's readDirectory host method with a virtual tree is complex (and TS doesn't expose its helpers here).

@devversion devversion added P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent merge safe target: major This PR is targeted for the next major release labels May 14, 2020
@googlebot googlebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label May 14, 2020
@devversion devversion changed the title refactor: ensure paths type safely passed around in ng-update refactor: ensure paths are safely passed around in ng-update May 14, 2020
@devversion devversion marked this pull request as ready for review May 14, 2020 16:08
@devversion devversion requested a review from jelbourn as a code owner May 14, 2020 16:08
Copy link
Member

@crisbeto crisbeto left a comment

Choose a reason for hiding this comment

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

LGTM. It seems like something we can easily forget, but I don't see what we can do about it, aside from some kind of linting.

Schematics using the TypeScript compiler API have a significant issue
with paths. The problem is that the TypeScript compiler API intends to
rely fully on absolute paths, while ng-update and the devkit tree intend
to rely on project-scoped/relative paths.

This is problematic as it is straightforward to mix paths up, leading to
unexpected errors. For example, computing a relative path between a devkit
path and an absolute disk path results in a non-existent path.

To fix this ambiguity, we improve type safety of paths by using branded
primitives such as the `@angular-devkit/core` `Path` or an even more
strict type called `WorkspacePath`. A normal string is considered an
unresolved path and cannot be assigned to a `WorkspacePath`. Similarly a
`WorkspacePath` cannot be assigned to a `string`. This ensures that
resolved paths are not accidentally mixed with unresolved paths, and
that we can safely pass around unresolved and resolved paths without
loss of their semantics.

This supposedly fixes angular#19270,
where a devkit path and an absolute disk path result in an incorrectly
resolved resource. In CLI apps it's possible to reference resources
through absolute project-scoped paths. e.g. `/src/app/app.component.html`
@devversion devversion force-pushed the refactor/ng-update-path-ambiguity branch from ce323b5 to 41b99c0 Compare May 14, 2020 16:42
Copy link
Member

@jelbourn jelbourn left a comment

Choose a reason for hiding this comment

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

LGTM

The difference between relative and absolute paths reminds me of https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function

Are there issues we should file with either the CLI or TypeScript to push the ecosystem in a more consistent direction?

@jelbourn jelbourn added lgtm action: merge The PR is ready for merge by the caretaker labels May 14, 2020
@mmalerba mmalerba merged commit b70a409 into angular:master May 15, 2020
@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 Jun 15, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker cla: yes PR author has agreed to Google's Contributor License Agreement P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent target: major This PR is targeted for the next major release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants