0

I'm the developer and maintainer of a FOSS C++ library, call it libfoo.

There used to be just one variant of it; and I've made several numbered releases. Last year, I've created a second variant of libfoo (call it var2). The thing is, despite the new variant covering all functionality of var1, it uses a different approach. I won't go into the details (unless you think they're important), but - both the original var1 and var2 continue to be relevant, and I would like to release both, going forward. At the same time, they clash: Some of the API (and the code) is exactly the same; some is API-identical but with different implementations; some the API is slightly different (different signatures for the same function, different types or definitions of types etc).

Currently, I have these two variants on two different branches in the same GitHub repository; and the releases only come from the first. And whatever I think of doing about it, I am worried of potential consequences:

  • If I release the new variant using the same library name and repository, and a higher version number, it suggests the existing variant is deprecated and un-updated.
  • If I release the variants going back-and-forth between variants, it would be confusing and break things.
  • If I release both variants together, I'm releasing two clashing libraries which can't really be used together. Plus, what would I do about the library name?
  • If I split the variants into separate repositories, I'm afraid people will fail to notice at least one of the variants.
  • If I release both libraries together, I'm essentially guaranteeing large-scale code duplication (but can I avoid it at all?)

How would you recommend managing this situation with respect to: Repositories, versioning, releasing and release location, naming of everything (include inside the code and in the documentation), explaining the situation in README's, etc?

I would especially be interested in answers backed by your own experience with similar situations.

Additional information:

  • For me personally, var2 is "the successor" of var1; but there are reasons why many users might be perfectly fine with var1 and not want/need var2.
  • I am developing this library independently, so there are no large clients which need to be placated one way or the other.

If you want to take a peek, the library is here.

9
  • What is the intended relation between the two variants? Is var2 intended to be a long-term successor of var1? If I am a new user of your library, should I just use var2, or are there other considerations to base the decision on? Commented Oct 27, 2021 at 12:24
  • 1
    How many clients are using var1, and how many var2? Will one of them be deprecate? On you question on which lib name to choose is pretty nonsensical without knowing the semantical differences between those libs. Following your Github link, I cannot spot those two variants or their differences. Voting to close with "needs details or clarity".
    – Doc Brown
    Commented Oct 27, 2021 at 13:01
  • @BartvanIngenSchenau: Well, it's a bit complicated. For me personally, var2 is the successor; but there are reasons why people might want to keep their life simpler and only use var1 (e.g. less dependencies, less different than what they're used to). I would personally recommend that you use var2.
    – einpoklum
    Commented Oct 27, 2021 at 13:22
  • @DocBrown: I don't have "clients", actually... will clarify the question. Neither var1 nor var2 will be deprecated, I've already said this. The new variant is on the "driver-wrappers" branch.
    – einpoklum
    Commented Oct 27, 2021 at 13:23
  • @einpoklum: by "clients", I did not mean necessarily persons or organizations, but projects which use var1 and var2, or users of those libs. If you would have all those projects under your own control, you could deprecate var1 and just switch to var2, but that's not your situation, I guess?
    – Doc Brown
    Commented Oct 27, 2021 at 13:28

2 Answers 2

2

It sounds like going with two repositories (and, since you are using GitHub, all of the features associated with a repository - issues, pull requests, discussions, releases, wiki, security scanning) with distinct names. Since both libraries live in parallel, it seems like you are going to want to take advantage of not only source code control, but all of the other features associated with a GitHub repository to make your library accessible to end-users.

By using separate repositories, most of your concerns are alleviated.

The concern that people will fail to notice one of the varients can be resolved by writing a section of the README and put it in the README for both variants that helps potential users make an informed decision about which one to choose. You can also use the project's wikis to hold this information, perhaps even going into more detail than you would in a README.

The code duplication really isn't a concern. Even if the same code appears in both projects, the code is in two different contexts. The push against code duplication is, in my opinion, too strong. Not only do you need to consider the code, but the context in which the code lives.

2
  • Question is, which variant to keep in the original location and which to relegate as "the other variant". Also, how to treat the naming and versioning.
    – einpoklum
    Commented Oct 27, 2021 at 13:47
  • 1
    @einpoklum I would recommend keeping whatever is in your main branch associated with the current repository and moving the other one to a new repository. If you've done releases through GitHub, clean those up so all releases in a repository are one variant. As far as naming and versioning, that's totally up to you, but they don't have to be related at all.
    – Thomas Owens
    Commented Oct 27, 2021 at 14:15
2

I think in the described situation, var1 and var2 have become different "products", each with a life cycle of their own, not completely decoupled in their development, but at least partially, with the option of individual versioning and releasing. First, I would make sure var1 and var2 have different names (ideally names which make the main differences clear), and have the related files not in two different branches, but two different folders of your working structure.

Putting those two variants in different repos is possible and makes most sense when you are going to have different maintainers for each variant. However, in case the development and maintenance of both variants is not fully decoupled, it is probably simpler to stick with one repo first. Nothing should hinder you to version and release two different products individually from the same repo.

If I release the new variant using the same library name and repository, and a higher version number, it suggests the existing variant is deprecated and un-updated.

Using two different names should solve this. However, it is also possible to use the "major version number" as part of the "advertising" name - just because Windows 11 is now the market, noone thinks Microsoft will stop publishing updates for Win 10 immediately. Or think of Python 2 and Python 3, as someone mentioned it in the comments - both are still living in parallel over years.

If I release the variants going back-and-forth between variants, it would be confusing and break things.

Not necessarily. Python 3 and Python 2 updates might be released simultanously or individually, I don't see a compelling reason why that confuses people or breaks things.

If I release both variants together, I'm releasing two clashing libraries which can't really be used together. Plus, what would I do about the library name?

Yes, you are releasing two libraries exactly because they cannot be used together - otherwise just one would be enough. And the library name is something you have to choose, we cannot really help you with this.

If I split the variants into separate repositories, I'm afraid people will fail to notice at least one of the variants.

That can be easily addressed by linking in the docs or project description of var1 to the other repo var2 (and vice versa), telling that there is a different variant, explain the differences and mention which one to use when.

If I release both libraries together, I'm essentially guaranteeing large-scale code duplication (but can I avoid it at all?)

Well, if you really want to maintain var1 and var2 over a long term, you may consider to refactor the duplicated code into a common lib which is used from var1 and var2 as well. In that situation, one repo is usually better working than two (or three, uf the lib would get its own). If, however, you just want to provide var1 as a "freezed" version, with no further maintenance, you can just live with the code duplication, since it won't require duplicate maintenance by you.

3
  • "Why" - because it's not like Python 2 and Python 3. Image you had a Pyton 4 release that built upon Python 2, then a Python 5 release that built on Python 3.
    – einpoklum
    Commented Oct 28, 2021 at 12:23
  • @einpoklum: an "advertising version number" would not be used that way - Python 2 and 3 are different products, and a successor in the "Python 2 product line" has always the name "Python 2.x". If you cannot adapt this naming scheme to your lib, choose two different names, like "cuda-api-wrappers-standard" and "cuda-api-wrappers-modern", or "cuda-api-wrappers-radio" vs. "cuda-api-wrappers-TV", or whatever you prefer.
    – Doc Brown
    Commented Oct 28, 2021 at 12:41
  • So, it'll have to be the second option I guess. I can't follow the Python scheme.
    – einpoklum
    Commented Oct 28, 2021 at 13:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.