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

Feature proposal: provide function to filter #1050

Merged
merged 14 commits into from Feb 20, 2022

Conversation

Primajin
Copy link
Contributor

While thinking about how to solve #1034 I was playing around a bit and came up with this draft.

The idea is that one can provide a function - for example via the .ncurc.js

target: (s) => { return s === matchesMyComplicatedChecksHere }

and then only get's back the matching packages. An alternative to a fancy regex where it can be solved more in detail and programmatically.

test provided:

/*dependencies: {
  mocha: '1.2'
  lodash: '^3.9.3'
  moment: '^1.0.0'
  chalk: '^1.1.0'
  bluebird: '^1.0.0'
}*/
    
it('filter dependencies by function', () => {
  getCurrentDependencies(deps, { filter: (s:string) => s.startsWith('m') }).should.eql({
    mocha: '1.2',
    moment: '^1.0.0'
  })
})

What do you think?

Copy link
Owner

@raineorshine raineorshine left a comment

Choose a reason for hiding this comment

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

Looks great!

  • Update cli-options.
  • Let's add tests for reject, filterVersion, and rejectVersion as well. I think they use the same predicate so they automatically get support for filter functions with this PR.
  • Pass name and versionRange to the predicate function as described here: [FR] Introduce safe option #1034 (comment). This will make it easier for developers to write conditions using the dependency version. In effect, filter and filterVersion will be identical when a function is passed. I think it's simpler than having two separate predicate signatures.

@Primajin
Copy link
Contributor Author

Primajin commented Feb 17, 2022

Hello there 👋🏻 😄
I am currently adding the tests for reject, filterVersion, and rejectVersion:


I found that test/getCurrentDependencies.test.ts has tests for filter and reject - but the tests for filterVersion and rejectVersion look very differently and are inside test/index.test.ts.
Are you ok if I add a couple more tests to test/getCurrentDependencies.test.ts in the same style as filter and reject but for filterVersion and rejectVersion?


Then I found that filter and filterVersion accept

filterVersion?: string | string[] | RegExp | RegExp[],

while reject and rejectVersion only accept:

rejectVersion?: string | string[] | RegExp,

Is that deliberate? If not, are you OK if I type them all with FilterRejectPattern ?
Does the JSDoc need to be updated as well?


Speaking of JSDoc - I'm not a native speaker so up to you to decide, but my IDE was nagging me about a missing the - shall I add it while at it?
the-highest

@Primajin
Copy link
Contributor Author

Oh apparently the CLI options are also contradicting with the types:

  {
    long: 'filter',
    short: 'f',
    arg: 'matches',
    description: 'Include only package names matching the given string, wildcard, glob, comma-or-space-delimited list, or /regex/.',
    type: 'string | string[] | RegExp',
  },
  {
    long: 'filterVersion',
    arg: 'matches',
    description: 'Filter on package version using comma-or-space-delimited list, or /regex/.',
    type: 'string | string[] | RegExp',
  },
  {
    long: 'reject',
    short: 'x',
    arg: 'matches',
    description: 'Exclude packages matching the given string, wildcard, glob, comma-or-space-delimited list, or /regex/.',
    type: 'string | string[] | RegExp | RegExp[]',
  },
  {
    long: 'rejectVersion',
    arg: 'matches',
    description: 'Exclude package.json versions using comma-or-space-delimited list, or /regex/.',
    type: 'string | string[] | RegExp | RegExp[]',
  },

vs.

  /**
   * Include only package names matching the given string, wildcard, glob, comma-or-space-delimited list, or /regex/.
   */
  filter?: string | string[] | RegExp | RegExp[],

  /**
   * Filter on package version using comma-or-space-delimited list, or /regex/.
   */
  filterVersion?: string | string[] | RegExp | RegExp[],

  /**
   * Exclude packages matching the given string, wildcard, glob, comma-or-space-delimited list, or /regex/.
   */
  reject?: string | string[] | RegExp,

  /**
   * Exclude package.json versions using comma-or-space-delimited list, or /regex/.
   */
  rejectVersion?: string | string[] | RegExp,

So they are exactly the opposite.

I would make them all string | string[] | RegExp | RegExp[] | Function now - ok?

@raineorshine
Copy link
Owner

I found that test/getCurrentDependencies.test.ts has tests for filter and reject - but the tests for filterVersion and rejectVersion look very differently and are inside test/index.test.ts.
Are you ok if I add a couple more tests to test/getCurrentDependencies.test.ts in the same style as filter and reject but for filterVersion and rejectVersion?

Sure!

Is that deliberate? If not, are you OK if I type them all with FilterRejectPattern ?
Does the JSDoc need to be updated as well?

It is not deliberate. I think they should have the same type. Thanks!

Speaking of JSDoc - I'm not a native speaker so up to you to decide, but my IDE was nagging me about a missing the - shall I add it while at it?

You are right! That code was written by a non-native speak also, but your IDE apparently is a native speaker :).

I would make them all string | string[] | RegExp | RegExp[] | Function now - ok?

Yes, I agree.

@Primajin
Copy link
Contributor Author

Primajin commented Feb 17, 2022

  • Update cli-options.
  • Let's add tests for reject, filterVersion, and rejectVersion as well. I think they use the same predicate so they automatically get support for filter functions with this PR.

done 😄

  • Pass name and versionRange to the predicate function as described here: #1034 (comment). This will make it easier for developers to write conditions using the dependency version. In effect, filter and filterVersion will be identical when a function is passed. I think it's simpler than having two separate predicate signatures.

Should this be part of this MR or a separate one - sunsetting filterVersion/rejectVersion feels like a breaking change that would require a major version bump - while the rest could be a new feature with a minor bump so far.
What do you think?

@raineorshine
Copy link
Owner

raineorshine commented Feb 17, 2022

  • Pass name and versionRange to the predicate function as described here: #1034 (comment). This will make it easier for developers to write conditions using the dependency version. In effect, filter and filterVersion will be identical when a function is passed. I think it's simpler than having two separate predicate signatures.

Should this be part of this MR or a separate one - sunsetting filterVersion/rejectVersion feels like a breaking change that would require a major version bump - while the rest could be a new feature with a minor bump so far. What do you think?

It should be part of this PR, since I don't want to publish the feature with the wrong predicate signature.

My intention was to keep filterVersion and rejectVersion, so this won't be a breaking change. It's just the function signature of the predicate function that is in question. You can pass the result of semverutils.parseRange(versionRange) as the second argument to the predicate, so that the developer can write conditions based on the version number.

@Primajin
Copy link
Contributor Author

🤔
Did you mean like this: Primajin@d21ec5a

Given:

 @types/chai-as-promised             ^7.1.4  →    ^7.1.5
 @types/node                       ^17.0.10  →  ^17.0.18
 @typescript-eslint/eslint-plugin   ^5.10.0  →   ^5.12.0
 @typescript-eslint/parser          ^5.10.0  →   ^5.12.0

.ncurc.js

filter: (name,version) => {return name.startsWith('@types') && version.startsWith('^7')},

yields:
image

Sorry if I can't fully follow.

@raineorshine
Copy link
Owner

Yes, but version should be of type semverutils.SemVer[]. We parse the version range for the developer to make it even easier to write conditions.

You can see semverutils.parseRange used throughout the codebase.

See: https://git.coolaj86.com/coolaj86/semver-utils.js#semverutils-parserange-rangestring

@Primajin
Copy link
Contributor Author

Sorry but I can't follow / understand how to implement that.
I am getting the current version as string from the package.json and then how should it be parsed into a range and decided as "this returns true now"?
Signing off for today, thanks for the comments and help though 🙂 👍🏻

@raineorshine
Copy link
Owner

No problem. I'll revisit when I have a moment.

@raineorshine
Copy link
Owner

This is what I had in mind: 13cafc5

The filterVersion predicate function signature doesn't match filter, but I'm going to leave it for now since the composeFilter pipeline needs major refactoring to support this.

It looks ready to merge from my perspective. Let me know if I'm missing anything.

@Primajin
Copy link
Contributor Author

Ahh cool thanks! 👍🏻 Let me take a final glimpse at it on Monday - thanks for your support!

@Primajin
Copy link
Contributor Author

OK couldn't wait until Monday 😅

Added a final cleanup commit with tiny changes:

  • src/lib/filterAndReject.ts:4 - we don't need to import all of semverutils here, we can just get the two things we need
  • src/types.ts:28 - FilterFunction isn't used outside any more, no need to export
  • test/getCurrentDependencies.test.ts - both of us added dangling commas, while I personally like them, it looks like the rest of the codebase doesn't use them - so let's adhere to the common style 😉

Very excited about this, it was a lot of fun - thank you!

@Primajin Primajin marked this pull request as ready for review February 19, 2022 15:43
@raineorshine
Copy link
Owner

Thanks!

  • test/getCurrentDependencies.test.ts - both of us added dangling commas, while I personally like them, it looks like the rest of the codebase doesn't use them - so let's adhere to the common style 😉

I need to add Prettier...

@raineorshine raineorshine merged commit 087ab09 into raineorshine:main Feb 20, 2022
@raineorshine
Copy link
Owner

Published to v12.4.0

Note that I am going to patch the filterVersion predicate when I have time to do the necessary refactoring. It should have the same signature as the filter predicate. I'll update the README and publish an official release then.

@Primajin Primajin deleted the override-filter branch February 20, 2022 14:03
@Primajin Primajin mentioned this pull request Feb 28, 2022
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