Tool to automatically suggest the next version number

191 views
Skip to first unread message

Adrian

unread,
Dec 22, 2016, 10:12:25 AM12/22/16
to Go Package Management
Hi Everyone,

I saw the post at https://blog.gopheracademy.com/advent-2016/saga-go-dependency-management/ which included a request for a tool to automatically suggest the next semver number for Go code and thought I'd build a proof-of-concept for fun.

It's based on a simple algorithm of:

Incrementing Major when API compatibility is broken.
Incrementing Minor when the package starts exporting something new.
Incrementing Build on every commit.

I haven't tried it on many repositories, yet, so YMMV. It's over at https://github.com/a-h/ver

Useful?

mhh...@gmail.com

unread,
Dec 22, 2016, 6:37:38 PM12/22/16
to Go Package Management
Hi,

SDBoyer did write an interesting analysis about how a program could
suggest the next version change.
It revealed that some situation were not identifiable properly.
can t put my hands on it again right now, maybe someone else remembers ?

Regarding your package, maybe you should rely on those two
https://github.com/Masterminds/vcs
https://github.com/Masterminds/semver

Also, imho, being able to define a since parameters would i pretty useful.
Rather than picking all commits, a program could drive it to work
only since a specified commit hash.

Adrian Hesketh

unread,
Dec 24, 2016, 8:05:49 AM12/24/16
to Go Package Management
Thanks!

'ver' doesn't include sub-dependencies in the decision of whether to bump the minor or major versions, so if a package you are analysing exports a struct from a different non-vendored package and that package has changed, then you could have broken API compatibility via the dependent package without knowing about it, so maybe that's it?

I was thinking of this as a tool to help people notice when they've changed their API and also handle the common case of go repos which haven't got any versioning on them. The bumped version numbers would let you know how the code you've used its changing, e.g. by building a sparkline of how the package's public API is changing over time.

Cheers for the pointer to masterminds/vcs repo, unless I'm missing something, it lacks a 'git log' type behaviour to list all of the commits in the repo, but it looks like it would be easy enough to submit a pull request to add it.

I've used SemVer before for parsing tags really successfully, but I tried to minimise relying on external packages to keep the code as simple as possible for now. I figured that if people thought 'ver' was a useful thing, I'd add support for parsing existing tags on repos and add SemVer in at that point.

Nice idea on starting from a commit hash - it would totally make sense to only start suggesting a version after the latest semver tag has been added to the repo, e.g. if the latest tag was 1.2.3, then 'ver' should suggest 1.2.4 rather than ignoring tags and doing its own thing.

mhh...@gmail.com

unread,
Dec 25, 2016, 2:16:30 PM12/25/16
to Go Package Management


On Saturday, December 24, 2016 at 2:05:49 PM UTC+1, Adrian Hesketh wrote:
Thanks!

'ver' doesn't include sub-dependencies in the decision of whether to bump the minor or major versions, so if a package you are analysing exports a struct from a different non-vendored package and that package has changed, then you could have broken API compatibility via the dependent package without knowing about it, so maybe that's it?

That s a case indeed. One way is to rely on the manifest,
but that excludes all non manifest based projects
which are legion
:x
I m not sure where you place the cursor.

Regarding my comment, in my souvenirs,
it was about pointer manipulation and ownership,
let s say, (a very obvious example)

func Pub() *Some{return &Some{}}
Changes to
func Pub() *Some{return nil}

Signature did not change, yet, a dependent library will break.


I was thinking of this as a tool to help people notice when they've changed their API and also handle the common case of go repos which haven't got any versioning on them. The bumped version numbers would let you know how the code you've used its changing, e.g. by building a sparkline of how the package's public API is changing over time.

agreed, i also thought about it again,
and came to think it could be useful to prevent wrong release tagging.
Like the op tries to bump to patch,
but the program detects the changes as a major one,
the operation could then be prevented.
 
 
Cheers for the pointer to masterminds/vcs repo, unless I'm missing something, it lacks a 'git log' type behaviour to list all of the commits in the repo, but it looks like it would be easy enough to submit a pull request to add it.

Possibly! I did point it for its support of the many various vcs.
Which, in my understanding, is a requirement.
 
I've used SemVer before for parsing tags really successfully, but I tried to minimise relying on external packages to keep the code as simple as possible for now. I figured that if people thought 'ver' was a useful thing, I'd add support for parsing existing tags on repos and add SemVer in at that point.

yes, agreed. maybe a solution to that would be to publish a pre built binary,
and a go gettable binary which would  in fact wrap call to the pre built binary.
If the pre built bin can not be found JIT on the GOBIN, then download it,
copy it into GOBIN, run it. Otherwise just run it.

That way you could be free to develop the way you like, while being
entirely compatible with go get until the new dependency manager is
released.

Nice idea on starting from a commit hash - it would totally make sense to only start suggesting a version after the latest semver tag has been added to the repo, e.g. if the latest tag was 1.2.3, then 'ver' should suggest 1.2.4 rather than ignoring tags and doing its own thing.
 
Yes

Sam Boyer

unread,
Dec 28, 2016, 9:34:27 AM12/28/16
to Go Package Management
hi Adrian,

so psyched that you took it upon yourself to write this! i hope to give it a test drive this week. in the meantime, comments here...


On Saturday, December 24, 2016 at 8:05:49 AM UTC-5, Adrian Hesketh wrote:
Thanks!

'ver' doesn't include sub-dependencies in the decision of whether to bump the minor or major versions, so if a package you are analysing exports a struct from a different non-vendored package and that package has changed, then you could have broken API compatibility via the dependent package without knowing about it, so maybe that's it?

Yes, this general area is the biggest issue - because Go allows types to be pulled up and re-expressed from one package into another (through various means), fully inspecting any non-primitive type could entail a transitive exploration of constituent types. If we accept that it's possible to use a project with different versions of its dependencies (which we should, and the new tooling does), then version numbers can necessarily only describe the local, non-transitive type information.

This is generally fine, as long as:

1. Changes within a given major version are addition-only; no types are modified or removed
2. Constraints are generally declared as open up to the next major version (e.g., >=1.2.0, <2.0.0)

We achieve #1 through the sort of tool you've worked on here, and #2 through sane defaults in the dep mgmt tool.
 

I was thinking of this as a tool to help people notice when they've changed their API and also handle the common case of go repos which haven't got any versioning on them. The bumped version numbers would let you know how the code you've used its changing, e.g. by building a sparkline of how the package's public API is changing over time.

Interesting! There's lots of possible applications for tooling like this; I'd not thought of this one.
 

Cheers for the pointer to masterminds/vcs repo, unless I'm missing something, it lacks a 'git log' type behaviour to list all of the commits in the repo, but it looks like it would be easy enough to submit a pull request to add it.

There's a method that allows you to execute arbitrary commands.

You also may find that some of the work you need to do is facilitated by https://godoc.org/github.com/sdboyer/gps#SourceManager, and in particular ListVersions(). The new tooling we're working runs on gps, so you'd be implicitly following along by building on gps. If you do go that route, it's probably be good to ping me in the gopher slack, as there's at least one subtlety there that my docs are behind on, relevant to revisions.

I'd also happily consider additions to gps' API to facilitate this use case.
 

I've used SemVer before for parsing tags really successfully, but I tried to minimise relying on external packages to keep the code as simple as possible for now. I figured that if people thought 'ver' was a useful thing, I'd add support for parsing existing tags on repos and add SemVer in at that point.

That Masterminds/semver project is also what gps relies on, so you'd still be in line with the current direction of work.
Reply all
Reply to author
Forward
0 new messages