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

fix(package-graph): Flatten cycles to avoid skipping packages #2185

Merged
merged 22 commits into from Jul 18, 2019

Conversation

nicolo-ribaudo
Copy link
Contributor

@nicolo-ribaudo nicolo-ribaudo commented Jul 16, 2019

Description

To correctly handle cycles, I wrote an algorithm which flattens cycles into single nodes. Then every cycled, when it becomes a "leaf node", can be normally executed.

Example:

          +---+
   /----> | B |
  |       +---+
  |
+---+     +---+ <----\
| A | --> | C |       |
+---+     +---+ --\   |
                   |  |
          +---+ <-/   |
          | D |       |
          +---+ -----/
            |
            v
          +---+
          | E |
          +---+

Becomes

          +---+
   /----> | B |
  |       +---+
  |
+---+     +-------+
| A | --> | C + D |
+---+     +-------+
              |
              v
            +---+
            | E |
            +---+

Now that there aren't anymore nodes, E and B can be executed since they are leaf nodes. The graph becomes:

+---+     +-------+
| A | --> | C + D |
+---+     +-------+

C + D now is a leaf node, so C and D can be executed. The cycle is then removed from the graph.

At this point, A becomes a leaf node and can be executed.

Note that two cycles might have an intersection (or be nested): in that case they are handled as a single cycle.

Context

Fixes #2107
Need to check: #2165 (@alcferreira)

How Has This Been Tested?

It fixed our problem in the Babel publishing process.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

@nicolo-ribaudo nicolo-ribaudo changed the title Add wrong test Fix cycle detection in "lerna version" Jul 17, 2019
@nicolo-ribaudo nicolo-ribaudo force-pushed the cycle-parent-version-bug branch 2 times, most recently from b619ccb to 0f0dae2 Compare July 17, 2019 20:16
Copy link
Contributor Author

@nicolo-ribaudo nicolo-ribaudo left a comment

Choose a reason for hiding this comment

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

I will mark this PR as ready after I have tested it with Babel.

I suggest reviewing it with whitespace diff disabled (https://github.com/lerna/lerna/pull/2185/files?w=1)

utils/pack-directory/__tests__/pack-directory.test.js Outdated Show resolved Hide resolved
commands/run/__tests__/run-command.test.js Show resolved Hide resolved
commands/run/__tests__/run-command.test.js Show resolved Hide resolved
core/package-graph/index.js Show resolved Hide resolved
core/package-graph/index.js Show resolved Hide resolved
core/package-graph/index.js Show resolved Hide resolved
core/package-graph/index.js Show resolved Hide resolved
@nicolo-ribaudo
Copy link
Contributor Author

nicolo-ribaudo commented Jul 17, 2019

Oh this PR makes lerna warn about 6 cycles in Babel (instead of about 30), making it way more actionable to resolve 😄

And it seems to correctly update every package 😎

@nicolo-ribaudo nicolo-ribaudo marked this pull request as ready for review July 17, 2019 20:50
Copy link
Member

@evocateur evocateur left a comment

Choose a reason for hiding this comment

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

I'm very impressed by this PR, thanks so much! (and huge apologies for the pain!)


Cycles:
B -> C -> D -> E -> B
B -> C -> F -> G -> B
Copy link
Member

Choose a reason for hiding this comment

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

I love the graphs!

commands/run/__tests__/run-command.test.js Show resolved Hide resolved
commands/run/__tests__/run-command.test.js Show resolved Hide resolved
core/package-graph/index.js Show resolved Hide resolved
core/package-graph/index.js Show resolved Hide resolved
utils/pack-directory/__tests__/pack-directory.test.js Outdated Show resolved Hide resolved
core/package-graph/index.js Outdated Show resolved Hide resolved
core/package-graph/index.js Show resolved Hide resolved
core/package-graph/index.js Show resolved Hide resolved
@evocateur
Copy link
Member

I have no idea why the exec+run tests are flaking (inconsistently!) in CI. I'm fixing that now, then I'll merge.

Copy link
Contributor

@bweggersen bweggersen left a comment

Choose a reason for hiding this comment

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

Really great work! I love how you solved the problem at the right abstraction and simplified the way we should reason about cycles. I had to re-read the visits() function a few times to "get it". Especially lines 378-380, 384 and 391 in package-graph/index.js. There's a lot going on!

I'm grateful you were able to solve this so well, and I'm sorry this was a problem in the first place. I learned a lot reviewing your code!

|
+---+ +---+ <----\
| A | --> | C | |
+---+ +---+ <-\ |
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: C and D's dependency lines should only point one direction each, right?

Copy link
Member

Choose a reason for hiding this comment

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

Good catch, I've fixed this

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks!

@nicolo-ribaudo
Copy link
Contributor Author

@evocateur Thanks for your new commits ☺️

@evocateur
Copy link
Member

ok ok i'm done tweaking i swear

@evocateur evocateur changed the title Fix cycle detection in "lerna version" fix(package-graph): Flatten cycles to avoid skipping packages Jul 18, 2019
@evocateur evocateur merged commit b335763 into lerna:master Jul 18, 2019
@evocateur
Copy link
Member

@nicolo-ribaudo @bweggersen Huge thanks for all your help!

@nicolo-ribaudo nicolo-ribaudo deleted the cycle-parent-version-bug branch July 18, 2019 20:12
abernix added a commit to apollographql/apollo-server that referenced this pull request Jul 24, 2019
Thanks to a gracious fix to Lerna by the Babel community, this issue
(originally reported in my lerna/lerna#2107) is no
longer an issue in new versions of Lerna, thanks to the fix provided in
lerna/lerna#2185.

Ref: lerna/lerna#2185
Ref: lerna/lerna#2107
nicolo-ribaudo added a commit to babel/babel that referenced this pull request Sep 6, 2019
v3.16 includes lerna/lerna#2185,
which fixes an issue we had in the v7.5 releases
abernix added a commit to apollographql/apollo-tooling that referenced this pull request Sep 6, 2019
> In the same spirit as `apollo-server`:
> apollographql/apollo-server@585085d4d8dd7ab

Thanks to a gracious fix to Lerna by the Babel community, this issue
(originally reported in my lerna/lerna#2107) is no
longer an issue in new versions of Lerna, thanks to the fix provided in
lerna/lerna#2185.

Ref: lerna/lerna#2185
Ref: lerna/lerna#2107

cc @JakeDawkins
cc @trevor-scheer
trevor-scheer pushed a commit to apollographql/apollo-tooling that referenced this pull request Sep 6, 2019
* Stop pinning Lerna to pre v3.14.0.

> In the same spirit as `apollo-server`:
> apollographql/apollo-server@585085d4d8dd7ab

Thanks to a gracious fix to Lerna by the Babel community, this issue
(originally reported in my lerna/lerna#2107) is no
longer an issue in new versions of Lerna, thanks to the fix provided in
lerna/lerna#2185.

Ref: lerna/lerna#2185
Ref: lerna/lerna#2107

cc @JakeDawkins
cc @trevor-scheer

* chore(deps): update dependency lerna to v3.16.4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3.14.x: Prerelease publish failed to bump version in most package.json files.
3 participants