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 for issue #43. install peer deps doesn't update a peer dep when a… #46

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

nathanhleung
Copy link
Owner

… more recent version is already installed.

…r dep when a more recent version is already installed.
* Read package file file from disk.
* Returns undefined if no package file exists.
*/
function readPackageFile() {
Copy link
Owner Author

Choose a reason for hiding this comment

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

Could you add a test for this function in install-peerdeps.test.js under the getPackageData test?

Choose a reason for hiding this comment

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

Copy link
Owner Author

Choose a reason for hiding this comment

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

Thanks, I'll take a look!

}
});
} else {
resolve();
Copy link
Owner Author

Choose a reason for hiding this comment

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

My understanding of what occurs in this line is that if the package file does not exist, readPackageFile resolves to undefined. Is this the desired behavior?

Choose a reason for hiding this comment

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

Yes, that's because I'm not assuming there is a package file.

It's possible there isn't one in the current directory.

Copy link
Owner Author

Choose a reason for hiding this comment

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

Of course, just checking as I wasn't sure if you wanted to reject with an error or resolve with false instead -- regardless I see you're checking for truthiness below this line anyways, so undefined works for me.

}
readPackageFile()
.then(localPackageFile =>
getPackageData({ encodedPackageName, registry, auth, proxy })
Copy link
Owner Author

Choose a reason for hiding this comment

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

One way we can flatten this Promise tree is something like this:

let localPackageFile;
readPackageFile()
	.then(l => {
		localPackageFile = l;
		return getPackageData({ encodedPackageName, registry, auth, proxy });
	})
	.then(data => {
		// ...
		// body of function
		// ...
	})
	.catch(err => cb(err));

I think it'll make the function a bit easier to read/reason about!

Choose a reason for hiding this comment

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

Personally I'm not keen on setting variables outside the promise callbacks.

Normally these days I use async/await instead of raw promises. You should consider using async/await if you want it easier to read and reason about ;)

Copy link
Owner Author

@nathanhleung nathanhleung Jan 20, 2019

Choose a reason for hiding this comment

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

I agree -- async/await is a beautiful abstraction over callbacks and Promises!

Unfortunately, there's a project at Airbnb which depends on this project maintaining compatibility with Node.js 0.10 and 0.12, and I don't want to use async/await yet as I'm not completely sure if regeneratorRuntime has dropped support for earlier Node versions -- so that's why we're staying with Promises for now.

While potentially awkward, setting variables outside of the promise callback is the best way I know of to keep the line depth small (avoiding the pyramid of doom!). If you can think of another way to use promises without nesting the inner promise more deeply while still keeping the localPackageFile variable in scope, though, I welcome that too.

.then(() => {
const cli = spawnCli("data-forge-indicators", "has-newer-peer-dep");
cli.on("exit", code => {
t.equal(code, 0, `errored, exit code was ${code}`);
Copy link
Owner Author

Choose a reason for hiding this comment

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

This might help with the tests in general -- if you add a third argument like

t.equal(/\byarn global\b/.test(cmd), true, `errored, got ${cmd}`);

to the failing tests, you'll be able to see what's going on.

Choose a reason for hiding this comment

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

I'm not sure what you mean.

Where does the cmd variable come from?

Copy link
Owner Author

@nathanhleung nathanhleung Jan 20, 2019

Choose a reason for hiding this comment

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

Forgot to mention, but it's from another test a few lines below:

test("places `global` as first arg following `yarn` when using yarn and `--global` is specified", t => {
  getCliInstallCommand(["eslint-config-airbnb", "--global", "-Y"]).then(
    command => {
      const cmd = command.toString();
      t.comment(cmd);
      t.equal(/\byarn global\b/.test(cmd), true);
      t.end();
    },
    t.fail
  );
});

@nathanhleung
Copy link
Owner Author

nathanhleung commented Jan 20, 2019

@ashleydavis thank you for reading over my comments and taking the time to respond, and thanks for the new test. I hope my responses are helpful and I'm happy to provide more clarification too.

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.

None yet

2 participants