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

refactor(dep-check): introduce the new configuration schema #1911

Merged
merged 10 commits into from
Oct 13, 2022

Conversation

tido64
Copy link
Member

@tido64 tido64 commented Sep 30, 2022

Description

Introduces the new config schema. In particular, the old -> new config migration is implemented along with the check command. This can be flipped on with an env variable.

Test plan

Build align-deps:

cd packages/align-deps
yarn build --dependencies
cd ../test-app

Change the test app's target prod version to 0.70:

diff --git a/packages/test-app/package.json b/packages/test-app/package.json
index 43107f04..3a138093 100644
--- a/packages/test-app/package.json
+++ b/packages/test-app/package.json
@@ -61,7 +61,7 @@
     "preset": "@rnx-kit/scripts"
   },
   "rnx-kit": {
-    "reactNativeVersion": "^0.68",
+    "reactNativeVersion": "^0.70",
     "kitType": "app",
     "build": {
       "distribution": [

Run align-deps:

node ../align-deps/lib/cli.js

Follow the instructions on screen, and repeat the command. The warnings should go away.

@tido64 tido64 mentioned this pull request Sep 30, 2022
24 tasks
@tido64 tido64 force-pushed the tido/dep-check-v2 branch 2 times, most recently from 610adaa to b910879 Compare October 6, 2022 08:31
Copy link
Contributor

@afoxman afoxman left a comment

Choose a reason for hiding this comment

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

It's exciting to see align-deps coming along! Sorry this took me so long to get to.

I left comments throughout the code, and had a few PR-wide comments as well:

  1. The package is getting complex, and so the individual functions and code segments are going to be harder to "parse" and understand.

One thing that would help is comments, both at the function level and in lengthy blocks that are doing key data transformations.

Another is function names that express the data query or transform that is happening. For example, v2_profilesSatisfying. As an outsider who isn't immersed in dependency management/alignment challenges, I'm not sure what this name is telling me. Also, in this case, the function operates on requirements and presets, not profiles. So maybe "v2_filterAndMergePresetsSatisfyingRequirements". And this name is ugly, and leads me to think there are probably two or three functions it should split into.

  1. Old vs New config. It seems like there's a straightforward, automatic way to internally transform from old to new. Internally, I see hints of the old config here and there. I'm wondering if you can localize these, pushing up to the CLI/API entry point? When an old config comes in, do a single transform, and then the other 95% of align-deps operates only on the new config. I realize this muddies error-reporting. e.g. telling users about 'preset X' and 'requirement R' in a message could confuse them if they're on the old config. They may still have enough info to puzzle it out, though, and you could append a link to new config in the error message if they want to learn more. There is value in both customer happiness and tool usability.

packages/config/src/kitConfig.ts Show resolved Hide resolved
packages/dep-check/src/check.ts Outdated Show resolved Hide resolved
packages/dep-check/src/check.ts Outdated Show resolved Hide resolved
packages/dep-check/src/check.ts Outdated Show resolved Hide resolved
packages/dep-check/src/check.ts Outdated Show resolved Hide resolved
packages/dep-check/src/compatibility/config.ts Outdated Show resolved Hide resolved
packages/dep-check/src/dependencies.ts Outdated Show resolved Hide resolved
packages/dep-check/src/presets/microsoft/react-native.ts Outdated Show resolved Hide resolved
packages/dep-check/src/profiles.ts Outdated Show resolved Hide resolved
packages/dep-check/src/profiles.ts Outdated Show resolved Hide resolved
Copy link
Member Author

@tido64 tido64 left a comment

Choose a reason for hiding this comment

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

I should have made this clearer in the description. The scope of this PR is limited to the new config schema, and the check command. As such, dep-check will be in a state of messy mash of both v1 and v2 until we've migrated everything.

Currently, the plan is to:

  1. Migrate commands to the new config schema
  2. Copy all code to a new package, align-deps
  3. Remove all v1 code
  4. Publish align-deps
  5. Have dep-check wrap align-deps with a warning about the name change

But if this is confusing, maybe it makes more sense to swap 1 and 2 here. What do you think?

packages/dep-check/src/check.ts Outdated Show resolved Hide resolved
packages/dep-check/src/check.ts Outdated Show resolved Hide resolved
packages/dep-check/src/check.ts Outdated Show resolved Hide resolved
return checkPackageManifest(manifest, options);
};
const check =
process.env["DEP_CHECK_VERSION"] === "2"
Copy link
Member Author

Choose a reason for hiding this comment

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

I don't expect DEP_CHECK_VERSION to be long lived. It only exists now while I implement v2. Mostly for making testing easier. It's not meant to be public.

...(customProfilesPath ? [customProfilesPath] : []),
],
requirements:
kitType === "app"
Copy link
Member Author

Choose a reason for hiding this comment

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

This config is also stringified and printed to the user further down. Added a comment here.

packages/dep-check/src/compatibility/config.ts Outdated Show resolved Hide resolved
packages/dep-check/src/dependencies.ts Outdated Show resolved Hide resolved
packages/dep-check/src/presets/microsoft/react-native.ts Outdated Show resolved Hide resolved
packages/dep-check/src/profiles.ts Outdated Show resolved Hide resolved
packages/dep-check/src/profiles.ts Outdated Show resolved Hide resolved
@tido64
Copy link
Member Author

tido64 commented Oct 10, 2022

I will rebase this PR when #1927 lands.

@tido64 tido64 force-pushed the tido/dep-check-v2 branch from 4888388 to 2c5ad0a Compare October 10, 2022 12:53
@tido64 tido64 force-pushed the tido/dep-check-v2 branch from c2c3a2a to c776457 Compare October 10, 2022 18:05

const devPreset = (() => {
if (kitType === "app") {
// Preset for development is unused when the package is an app.
Copy link
Contributor

Choose a reason for hiding this comment

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

sidenote: we need to make sure this is clear in the docs - I can see people not be aware

Copy link
Contributor

@kelset kelset left a comment

Choose a reason for hiding this comment

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

overall, given that the logic changes are already happening in the new package, I think we can go ahead and merge this.

Thanks for all your work Tommy, really appreciate that you keep the testing side up to date and enhanced with more tests.

I've left a few comments but they are all things not strictly related to the code

Copy link
Contributor

@afoxman afoxman left a comment

Choose a reason for hiding this comment

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

Seeing align-deps separate from dep-check makes things easier to understand. I have some new questions from this round of feedback, and a few unresolved comments from the last round.

I'll leave it to you to decide how and when to submit this PR and track the open items. I don't want to hold this up, but I would like those items addressed at some point.

If you submit this PR as-is, can you mark the align-deps version as 0.x or 0.0.x and use an '-alpha' prerelease tag for now?

}

function resolve(
{ kitType, alignDeps, manifest }: AlignDepsConfig,
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
{ kitType, alignDeps, manifest }: AlignDepsConfig,
{ kitType, alignDeps: { capabilities, presets, requirements }, manifest }: AlignDepsConfig,

Can you do nested destructuring like this? More of a curiosity than a suggestion...

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, you can. It affects legibility so I don't do it as much.

}

if (require.main === module) {
require("yargs").usage(
"$0 [packages...]",
"Dependency checker for React Native apps",
"Dependency checker for npm packages",
Copy link
Contributor

Choose a reason for hiding this comment

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

Is "Dependency checker" still the friendly name you want to use for align-deps?

Copy link
Member Author

Choose a reason for hiding this comment

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

Do you have any suggestions? This package is still private so there's still time to change it. I'll make it part of the docs update PR.

.map((v) => v.trim().split(".").slice(0, 2).join("."))
.map((v) => {
const coerced = semverCoerce(v);
return coerced ? `${coerced.major}.${coerced.minor}` : "0.0";
Copy link
Contributor

Choose a reason for hiding this comment

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

Are there times when this would realistically fail? And would you want to return a fake value when that happens, or fail the current manifest/run?

I'm guessing this happens if someone types something wrong in a preset file or in package.json. Seems like a good reason to just stop since you no longer can trust what you are looking at.

Copy link
Member Author

Choose a reason for hiding this comment

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

This function was moved in more recent changes. I'll make this throw in a later PR.

}

const filteredPreset = filterPreset(requirements, preset);
const filteredNames = Object.keys(filteredPreset);
Copy link
Contributor

Choose a reason for hiding this comment

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

Are the resulting filteredNames all packages which didn't meet the requirements in the preset? e.g. the stuff that is out of alignment?

Copy link
Member Author

Choose a reason for hiding this comment

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

I've added more comments around this in a separate PR, but what happens here is that we filter out profiles that do not fulfill the requirements. So filteredNames is the list of profile names that do satisfy the requirements.

: requirements.production;
}

if (kitConfig.reactNativeVersion) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be scoped to an "if old config is being used" check? Or will it be in the future?

Copy link
Contributor

Choose a reason for hiding this comment

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

Or maybe since this PR is now part of align-deps, will you add some deprecation warnings when you run into and make use of config like this?

Copy link
Member Author

Choose a reason for hiding this comment

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

This for detecting old config in third-parties. I don't know if it makes sense to output warnings here as it may be too noisy.

pkg.name === requiredPackage &&
"version" in pkg &&
semverSatisfies(
semverCoerce(pkg.version) || "0.0.1",
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there an example of when semverCoerce would legitimately fail, or is this the "0.0.1" an unlikely fallback? I'm not sure align-deps should try to run if it encounters a package with an invalid manifest. I think it's reasonable to fail and bail, rather than risk operating on other potentially bad data.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think this would fail if you fed it random strings. I don't expect this to fail often, but I've changed it to throw instead. I will also change the other sites, but in separate PRs since I've moved stuff around a bit.

@tido64
Copy link
Member Author

tido64 commented Oct 13, 2022

@afoxman, @kelset: Thanks for reviewing! I'm going to merge this now and will try to address all your concerns in upcoming PRs. I have five lined up already and they all depend on one another.

@tido64 tido64 merged commit e1d4b24 into microsoft:main Oct 13, 2022
@tido64 tido64 deleted the tido/dep-check-v2 branch October 13, 2022 09:16
@tido64 tido64 added the feature: align-deps This is related to align-deps label Oct 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature: align-deps This is related to align-deps
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants