Skip to content
This repository has been archived by the owner on Nov 10, 2022. It is now read-only.

fix: Reverse the direction of the semver check #16

Merged
merged 3 commits into from
Mar 5, 2021

Conversation

dyladan
Copy link
Member

@dyladan dyladan commented Mar 3, 2021

The semver check is backwards. It has not yet caused a bug because we haven't released any other 0.18.x

In the current 0.18 semver check if the user registers a global with version 0.18.0, then API module 0.18.1 attempts to access it, it will succeed. 0.18.1 may attempt to call a method which doesn't exist on 0.18.0. It should be the other way around. 0.18.0 should be able to access the 0.18.1 global because that global has at least the methods 0.18.0 expects.

I caught this while testing the semver check with fake versioning in my sample project

Copy link
Member

@vmarchaud vmarchaud left a comment

Choose a reason for hiding this comment

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

shouldn't we bump minor when adding new method on the API ? So the issue never happens

@codecov
Copy link

codecov bot commented Mar 4, 2021

Codecov Report

Merging #16 (81fdbb8) into main (493daa1) will decrease coverage by 0.01%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main      #16      +/-   ##
==========================================
- Coverage   94.65%   94.64%   -0.02%     
==========================================
  Files          39       39              
  Lines         505      504       -1     
  Branches       80       81       +1     
==========================================
- Hits          478      477       -1     
  Misses         27       27              
Impacted Files Coverage Δ
src/internal/global-utils.ts 90.32% <100.00%> (ø)
src/internal/semver.ts 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 493daa1...2b60af9. Read the comment docs.

@dyladan
Copy link
Member Author

dyladan commented Mar 4, 2021

Bumping minor when adding a new API method is what we will do.

Before This Fix

app API version behind dependency API version
  • End-user application (app) depends on API version 1.3.1
  • Dependency of app (dep) depends on API version 1.4.0
  • app registers global API 1.3.1
  • dep calls getGlobal and receives a 1.3.1 compliant object
  • dep calls a new method that doesn't exist on that object
app API version ahead of dependency API version
  • End-user application (app) depends on API version 1.4.0
  • Dependency of app (dep) depends on API version 1.3.1
  • app registers global API 1.4.0
  • dep calls getGlobal and receives undefined
  • dep uses noop even though it would have been safe to use the global API object

After This Fix

app API version behind dependency API version
  • End-user application (app) depends on API version 1.3.1
  • New method is added to the API and minor version is incremented
  • Dependency of app (dep) depends on API version 1.4.0
  • app registers global API 1.3.1
  • dep calls getGlobal and receives undefined
  • dep uses noop so everything is ok
app API version ahead of dependency API version
  • End-user application (app) depends on API version 1.4.0
  • Dependency of app (dep) depends on API version 1.3.1
  • app registers global API 1.4.0
  • dep calls getGlobal and receives a 1.4.0 compliant object
  • dep only knows methods that existed on 1.3.1 and still exist on 1.4.0 so everything is ok

Copy link
Member

@vmarchaud vmarchaud left a comment

Choose a reason for hiding this comment

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

overall fine, nit pick for the test

* - The minor version of the API module requesting access to the global API must be less than or equal to the minor version of this API
* - 1.3 package may use 1.4 global because the later global contains all functions 1.3 expects
* - 1.4 package may NOT use 1.3 global because it may try to call functions which don't exist on 1.3
* - If the major version is 0, the minor version is treated as the major and the patch is treated as the minor
* - Patch and build tag differences are not considered at this time
*
* @param ownVersion version which should be checked against
*/
export function _makeCompatibilityCheck(
Copy link
Member

Choose a reason for hiding this comment

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

makes me wonder if we couldn't just vendor semver package ? Seems error prone to re-implement the logic ourselves. That would weight for browser but i'm just throwing the idea out there

Copy link
Member Author

Choose a reason for hiding this comment

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

The semver satisfies is more strict than we are. This could be a good thing though. If global is 1.3.3, we will be able to call it from 1.3.2 and 1.3.4. With the semver package we would only be able to call it from 1.3.2. Semver will never say an earlier version of a package satisfies. This would require end-user applications to always have the latest patch versions. Honestly may not be such a bad thing.

Copy link
Member

Choose a reason for hiding this comment

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

Well, you can pimp a version like 1.3.3 to 1.3.x then semver.satisfies() will be fine with 1.3.0 and 1.3.5.
semver offers a lot APIs to parse/modify versions. It's also possible to e.g. include pre-releases.

I think if we need something in version checking which semver can't do it's most likely problematic.

Main question is do we want one more dependency in API. Don't think there is any real world node application out there which hasn't semver already in it's node_modules tree somewhere.
Can't tell for browser.

Copy link
Member Author

Choose a reason for hiding this comment

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

Without semver:

test/index-webpack.js    3.49 MiB  test/index-webpack

With semver:

test/index-webpack.js    3.66 MiB  test/index-webpack

Looks like a 0.17 MiB difference if we add the dependency.

Copy link
Member Author

Choose a reason for hiding this comment

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

Don't think there is any real world node application out there which hasn't semver already in it's node_modules tree somewhere

In my experience this is about right

Can't tell for browser.

I suspect it's much lower since semver is mostly used for dependency management and the browser doesn't often have reason for that after compilation

Copy link
Member Author

Choose a reason for hiding this comment

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

Well, you can pimp a version like 1.3.3 to 1.3.x then semver.satisfies() will be fine with 1.3.0 and 1.3.5.
semver offers a lot APIs to parse/modify versions. It's also possible to e.g. include pre-releases.

Yes these things are for sure possible. We need to decide what behavior we want in this regard either way.

Copy link
Member

Choose a reason for hiding this comment

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

We need to decide what behavior we want in this regard either way.

If we don't get concensus right now, i think we could still refactor this later as its purely internal.

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 revamped the test suite to be much more comprehensive and much more clear 2b60af9. Makes me more comfortable leaving the semver package out of it.

Copy link
Member Author

Choose a reason for hiding this comment

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

its purely internal.

It's not purely internal. If we adopt semver, we will get stricter checks for prerelease versions. If we release our version, then 1.0.0, 1.0.0-alpha.1, and 1.0.0-alpha.2 will all be compatible with each other in both directions, which means we will be unable to make any changes once we release RC.

test/internal/semver.test.ts Show resolved Hide resolved
const globalVersionParsed = {
major: +globalVersionMatch[1],
minor: +globalVersionMatch[2],
patch: +globalVersionMatch[3],
Copy link
Contributor

Choose a reason for hiding this comment

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

Semver also has "-+", considering we are about to release an "-RC1" this starts to get complicated...
By the time we add the extra checks how much more of that 0.17Mib would get consumed, while I'll big on minification, I'm also big on don't re-invent the wheel (unless absolutely necessary for perf or size). And as most CDN payloads are also GZip'd how much does that 0.17 shrink too?

Copy link
Contributor

Choose a reason for hiding this comment

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

ok, just noticed the tests below using "alpha".. so ignore the above about pre-release and build#

Copy link
Member Author

Choose a reason for hiding this comment

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

Someone note the time @MSNev advocated for an increased bundle size 🤣

@dyladan dyladan merged commit 46b2a4d into open-telemetry:main Mar 5, 2021
@dyladan dyladan deleted the reverse-semver branch March 5, 2021 18:59
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants