18

I have a program that runs on command-line, let's call it myprogram 1.0.1. It's published on GitHub.

Now I discovered that name already exist for a well-know software, so I want to change the name from myprogram to myprog. This, of course, will break the old usage of command since the user now must type myprog and not myprogram anymore.

The code remains the same.

Any suggestion?

Lawrence
  • 309
  • 2
  • 6
  • 25
    Since this is a backward incompatible API change, you should bump to 2.0.0. Changing the name of a command line app is backward incompatible because the name is part of the API, and scripts using the tool will stop working. – JacquesB Aug 11 '22 at 06:05
  • 8
    @JacquesB, Can you turn that comment into an answer? It actually is one. – Bart van Ingen Schenau Aug 11 '22 at 07:03
  • 9
    As a practical solution, I tend to agree with @JacquesB's approach. However, you might also consider the alternative POV that by publishing the software under a new name (if you actually change the package name and not just the executable) you essentially create a fork whose version numbering can be totally detached from the original, i e. you could just start `myprog` at 1.0.0 regardless of which version you reached in `myprogram`. – Hans-Martin Mosner Aug 11 '22 at 07:22
  • 5
    @Hans-MartinMosner please don't, it will confuse the heck out of people – user253751 Aug 11 '22 at 15:10
  • 3
    I know the example is fake, but in case it parallels the actual naming.... you're going in the wrong direction. A more abbreviated name is likely to also have collisions, as well as be confused as just an abbreviation for the well-known program. i.e. you should not change `myprogram` to `myprog` but to `program4whatzzit` – Ben Voigt Aug 11 '22 at 19:43
  • Who is the audience for this version number? I.e who pays attention to it? In particular is there any automated tool that read the version number and uses it for e.g. automatic dependency resolution? Can you edit your question to answer the above? I think without them it's impossible to give a good answer. – bdsl Aug 12 '22 at 13:14

5 Answers5

33

I think myprogram needs to release 1.1.0 which supports the myprog alias. If the user invokes myprogram then it should present a notice/warning to the programmer that this name will be deprecated in the next major version release.

Upon release of myprog 2.0.0, myprogram should no longer work. The release of 2.0.0 could be nothing more than a name change. This will help to make the transition easier for developers since they have to worry about just a single compatibility-breaking change.

An alternative route is to fork myprogram into myprog and issue an abandonment notice like PHPExcel did; https://github.com/PHPOffice/PHPExcel

Whether or not your software rename constitutes a bump down to 1.0.0 instead of 2.0.0 is not a choice I am familiar with.


Regardless, I don't think versioning is going to be the big stumbling block but rather the name change itself. It sounds like a headache especially if people come across old tutorials for myprogram and are not aware of the name change.


Aliasing example in PHP:

<?php
class myprogram
{
    function __construct()
    {
        trigger_error( 'myprogram is being renamed to myprog in v2.0.0. Please consider switching to myprog today.', E_USER_NOTICE );
    }
}

class myprog extends myprogram
{
    function __construct()
    {
        // empty to avoid calling myprogram's constructor
    }
}

$myprogram = new myprogram();
MonkeyZeus
  • 468
  • 3
  • 7
  • 2
    "I highly advise against releasing 2.0.0 the day after 1.1.0." - why would that matter? The major version bump signals there is a breaking change, so users can take the time they want before updating. – JacquesB Aug 11 '22 at 15:41
  • @JacquesB Good point. I guess I was worried about those people that auto-update without reading release notes but I guess those people are the masters of their own torture. – MonkeyZeus Aug 11 '22 at 15:50
  • 1
    I'm not sure what it means to "support the... alias"? A program has one specific identifying name on the system used to invoke it. Is there some system-level thing that allows two different names to invoke a program (specified internally by said program)? – Daniel R. Collins Aug 11 '22 at 15:52
  • @DanielR.Collins OP didn't specify a programming language so I provided a PHP example. Hopefully it helps. The implementation is obviously going to vary from language to language. – MonkeyZeus Aug 11 '22 at 16:04
  • You might want to upgrade the example to specifically skip the constructor when calling myprog, otherwise you'll get the notice for both versions. (I realize it's just an example, but it's still less confusing to have a good one.) – Erik Aug 11 '22 at 17:35
  • 1
    @Erik Thanks, updated. This is exactly why I hesitated to provide any example at all until I realized some people couldn't grok the concept presented. – MonkeyZeus Aug 11 '22 at 17:39
  • @Erik Now I'm just waiting for the next person to come a long and tell me that their `myprogram` constructor is special and cannot be skipped over. – MonkeyZeus Aug 11 '22 at 17:41
  • 3
    @DanielR.Collins You can pretty always make a new command line program that does nothing but calls another one. Certainly you can argue that it's technically two different programs with two different names, but it has the **effect** of two names for the same program. No special system-level support required (though you may need some if you want to make the indirection closer to unobservable). – Ben Aug 12 '22 at 06:46
  • @Ben: If MonkeyZeus intended to include two separate programs in the next release, than this answer would be improved by clarifying/explicating that. I'm still not sure what program #1 would be doing to "support" that. – Daniel R. Collins Aug 12 '22 at 17:11
  • @DanielR.Collins If you need help in a specific language to implement what I've described then try https://stackoverflow.com/. At least 25 people had zero issue understanding what is presented in the answer. – MonkeyZeus Aug 12 '22 at 17:43
  • @DanielR.Collins I believe in the first sentence they're using `myprogram` to refer to the **package** you release, rather than the actual command line program. A program doesn't necessarily need to do anything at all to "support" another name (depending on how you implement it), but the **package** "supports" a name by providing a program with that name. They're just suggesting that rather than change the name in one release you could make the migration easier by first releasing a version where it supports *both* the old and the new name, and then in a following version remove the old name. – Ben Aug 13 '22 at 01:20
  • 1
    @MonkeyZeus: Pople are probably confused because the question is about changing the name of a *command line program*, but your example seems to be about changing the name of a class, which is a completely different thing. Can you even write command line programs in PHP? – JacquesB Aug 13 '22 at 10:04
15

Since this is a backward incompatible API change, you should bump to 2.0.0. Changing the name of a command line program is backward incompatible because the name is part of the API, and scripts and other tools using the program will stop working.

It might seem a big version jump for such a tiny change. But in semantic versioning, the version numbers does not reflect how big the changes are. They only reflect how the changes impact other systems which use your program - do they need to be updated or not?

JacquesB
  • 57,310
  • 21
  • 127
  • 176
8

The semantic versioning defines versioning rules solely in relation with the API, as it aims to facilitate the management of dependencies between packages.

Regarding the command line you are in a grey area. It is a user interface but at the same time it could be considered as a programming interface (e.g. in scripts). So it's up to you to define how you see it:

  • You may consider that the programme name is part of the API. Since any shell script would break with your new version, i.e. no backwards compatibility, you would have a major version increment.

  • You may consider that the programme name is not part of the API and that it's only a particular binding. The real API (parameters and options) is unaltered. In this case, you should consider a minor increment.

A major version for no new functionality does not feel right. Offer as part of the installation script or in your API documentation an optional creation of an alias or a copy with the old name to ensure backward compatibility. You can then go for the minor version with good conscience.

Christophe
  • 74,672
  • 10
  • 115
  • 187
  • 14
    *"A major version for no new functionality does not seem right."* That's because your gut is still thinking in "marketing versioning" rather than "semantic versioning". In semantic versioning, that great new feature that will change your library from a niche product to a tool needed be every developer world wide will only cause a bump in the minor version, whereas a tiny bugfix that breaks backwards-compatibility in rare edge cases will cause a bump in the major version. It's by design. – Heinzi Aug 11 '22 at 14:28
  • 3
    "*The real API (arguments and options) is unaltered*", not `args[0]`. – Wes Toleman Aug 11 '22 at 15:17
  • 5
    You can't just decide that the program name is not part of the API! For command line programs, using the program name is how the program is invoked. Changing it is the same as changing the name of an option - it is a breaking change. – JacquesB Aug 11 '22 at 15:31
  • @WesToleman Do you have many programs that parse args[0] ? The only cases that I encountered were to avoid hard-coding the program name in the help display and other things that were exactly meant to make the code independent of the programme name. – Christophe Aug 11 '22 at 16:14
  • @Heinzi As explained in my last paragraph, there’s an easy way out to reconcile both views, the gut feeling and the semver logic. Providing a backward compatibility on this case is simple, and as semver is not for the executable but the package (and the API may be exposed via its documentation) there is no fundamental issue in the proposed approach. – Christophe Aug 11 '22 at 16:27
  • @JacquesB The semver doesn’t address the the API bindings. First of all, without changing the name you could break things if the command is installed outside of the path. You could in the general case have for distributed APIs a binding A for OS A and a binding B for OS B but for the same package and the same version. Likewise nothing prevents to add additional alias/symlinks (see last para) And you can very well consider that the name is not part of the API if the command is only called in interactive mode (i.e. it’s only a user interface not meant for extensive scripting). – Christophe Aug 11 '22 at 16:42
  • 1
    @Christophe regarding parsing of `argv[0]`, I can think of plenty examples, most of them had to do with displaying a warning when the program was invoked via the old name. And of course there are also multicall binaries like Busybox or some builds of GNU coreutils, where the name used for invocation determines what the executable actually does. – Austin Hemmelgarn Aug 11 '22 at 16:54
  • @AustinHemmelgarn Is this something that you'd recommend? – Christophe Aug 11 '22 at 17:20
  • 1
    @Christophe For handling of the transition to a new name? Definitely. The usual setup is that you install the binary with the new name, and then have a symlink with the old name pointing at the new one. Then you just check `argv[0]` to decide whether to warn the user about the changed name or not when invoked. The multicall binary thing is much more specialized, but makes sense in some use cases (such as the typical use case for Busybox of providing most of the basic shell environment on a minimalistic system). – Austin Hemmelgarn Aug 11 '22 at 19:56
  • @Christophe, oops, looks like I've caused a distraction with my tongue-in-cheek way of putting it. Most programs don't change their behaviour depending on `argv[0]`. However, renaming an executable is equivalent to renaming a library function. As a concrete example I had a build process that downloaded a tool, added the download location to `PATH` and then called it to generate a version number. Renaming the tool would have broken my build. If it breaks my build it's a breaking change. – Wes Toleman Aug 12 '22 at 02:10
  • @WesToleman for another tongue-in-cheek response, your last sentence immediately brings to mind this [XKCD comic](https://xkcd.com/1172/) :) – justhalf Aug 12 '22 at 04:44
4

The purpose of semantic versioning is effectively to communicate a certain kind of change to the users of an API. But when you change the name of a command line tool, this alone seems to be a very clear communication to any command line programmer that the API has changed.

So you can change the major or minor version number, if you like, or keep it, or set it down to 1.0 for the new name, it will actually don't matter. If your intent is to show to the users that no functionality has changed, you should probably keep the old version number. But because of the name change, they cannot rely on that alone and will have to read your changelog either.

Doc Brown
  • 199,015
  • 33
  • 367
  • 565
3

The semantics of your code haven't changed - if I call your code, it will act exactly as before. What changes is how I call it (which name to use). But that's something the user most likely could have done themselves. I can rename an executable file that I downloaded, and that doesn't change it's semantic version.

Exception is if the name of the executable is relevant to it its operation. For example, at runtime your code would read the name of the executable "myprogram" and would create a directory "caches/myprogramcache". And that stops working when the executable is renamed to "myprog" because now it looks for a directory "caches/myprogcache". Probably best to avoid this.

gnasher729
  • 42,090
  • 4
  • 59
  • 119
  • 6
    Semantic versioning is not about the semantics of the code, it is about the semantics of the version number - i.e. the version numbers have meaning rather than being random. And the semantics of version number indicates if there are breaking API changes,. – JacquesB Aug 11 '22 at 15:06