Skip to content

feat: Add truncate function#855

Open
pjohnmeyer wants to merge 7 commits intonpm:mainfrom
pjohnmeyer:feat/add-truncate-function
Open

feat: Add truncate function#855
pjohnmeyer wants to merge 7 commits intonpm:mainfrom
pjohnmeyer:feat/add-truncate-function

Conversation

@pjohnmeyer
Copy link
Copy Markdown
Contributor

@pjohnmeyer pjohnmeyer commented May 3, 2026

This PR adds a truncate function to allow for portions of a version string "below" a certain level to be dropped.

The truncate function, as implemented in this first pass at a PR, returns a new valid version string. The function:

  1. Always removes build information
  2. Removes pre-release information, unless a pre-release type is passed as the truncation
  3. Zeroes out "lower" components of the semantic version (e.g. if the truncation performed is major, both minor and patch are zeroed)

An alternative I considered was returning strings without the valid version guarantee; for example, truncate('1.2.3', 'minor') === '1.2') instead of 1.2.0. This is not what was specified by @isaacs in #48, however, and seemed to be out of place for the rest of the library.

As a result, I also considered naming the function differently. One option I considered was floor, which seemed conceptually correct for major, minor, and patch. For truncation = 'pre*' however, this did not feel right, as truncate('1.2.3-rc1+build', 'prerelease') === '1.2.3-rc1', but since a) build metadata "...MUST be ignored when determining version precedence...", and b) there could be a 1.2.3-rc0 that is closer to the "floor", the name didn't seem right for that use case.

Lastly, I considered disallowing the pre* versions for the truncation argument, and only allowing major, minor, and patch. This, paired with the floor naming, was the most attractive alternative to me.

References

Related to #48

@pjohnmeyer pjohnmeyer requested a review from a team as a code owner May 3, 2026 00:37
@pjohnmeyer
Copy link
Copy Markdown
Contributor Author

pjohnmeyer commented May 3, 2026

FWIW: I don't have a stake in whether or not truncate is added to the library. I don't know if it's truly needed. I just saw an old issue and decided to work on it for fun. This also was useful for me to prepare to work on the dec function from #48, which I do actually see more of a use case for.

Also, I will note that template-oss-check failed and wanted me to update a bunch of .github files, but I did not include those per the CONTRIBUTING guidelines.

Copy link
Copy Markdown
Contributor

@mbtools mbtools left a comment

Choose a reason for hiding this comment

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

You could add some cases with prerelease and build to the fixtures, but LGTM 👍

Copy link
Copy Markdown
Contributor

@owlstronaut owlstronaut left a comment

Choose a reason for hiding this comment

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

This is great. I like the idea from @mbtools to add some prerelease+build fixtures. I'd like to see a test that verifies/catches the mutation i think happens.

orig = new SemVer('1.2.3-alpha+build')
snapshot = { orig stuff }
truncate(orig, 'major')
org === snapshot
 truncate(orig, 'patch') // second call should start from the orig

Comment thread README.md Outdated
Comment thread functions/truncate.js
return null
}

const parsed = parse(version, options)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

i think this returns the same instance of the SemVer class so you'll be mutating the caller's object.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good point! I saw how inc does it and didn't understand why it didn't use parse -- now it makes sense.

Co-authored-by: Michael Smith <owlstronaut@github.com>
@pjohnmeyer
Copy link
Copy Markdown
Contributor Author

I like the idea from @mbtools to add some prerelease+build fixtures. I'd like to see a test that verifies/catches the mutation i think happens.

@owlstronaut yeah I agree. I covered that functionality with the valid-versions fixture, but that's a less obvious expression of intent.

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 participants