Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add explicit versioning and publish versioned .jars #91

Open
AlexLandau opened this issue Sep 24, 2015 · 12 comments
Open

Add explicit versioning and publish versioned .jars #91

AlexLandau opened this issue Sep 24, 2015 · 12 comments

Comments

@AlexLandau
Copy link
Member

The modern way to do versioning is Semantic Versioning (http://semver.org/).

If people are just modifying checkouts of GGP-Base and running their applications from source, we don't really need versioning. If they're going to use it as a dependency from a separate project, publishing versioned jars is important. There's already an artifact on Maven Central involving some version of GGP-Base: http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22ggp-base%22 I believe this was used for incorporating it into a codebase in another JVM language.

Publishing to a Maven repository would be nice (and is doable through Gradle, with some effort) but may not be necessary; it's also possible to publish versioned .jars on Github. Those should come with instructions regarding which dependencies are necessary (and we should make the versions of dependencies explicit, so users can determine if they can replace them with other versions to satisfy their other dependencies). Publishing to Maven would probably require defining dependencies that we get online (handled by Gradle) rather than including them in the repo.

It's also possible that we should restructure GGP-Base to better work as a library. For example, we could have one project as the "library", another for sample gamers that depends on the library, and a third project containing the applications that depends on both the others. A user could insert their own gamer's project next to the sample-gamer project and add a dependency to the applications on their project. The first project could likely also be subdivided. (They should stay in the same repo under the same versioning scheme, though. They would be in separate Eclipse projects and produce separate artifacts.)

@AlexLandau
Copy link
Member Author

The real issue of adding semantic versioning (which I didn't make clear enough above) is that it requires a notion of an API for the library. Right now, that's not especially well-defined in GGP-Base. (Does a change of behavior when running against an existing game constitute an API change? How about a game that could exist but doesn't yet?)

On the other hand, you can put this off as long as you keep a major version of 0.

@samschreiber
Copy link
Member

Some initial thoughts: I think that ggp-base can be separated into layers.

  • util/ forms the bottom layer, defining a lot of the basic concepts in ggp-base.
  • player/, server/, and validator/ form an intermediate layer, building the major important systems on top of the basic concepts defined in util/
  • apps/ forms the top layer, combining the parts defined in lower layers into actual applications that can be run independently

In terms of dependencies, I think that util/ should be self-contained, and {player/, server/, validator/} should depend on util/ (and themselves) but not on anything else, and apps/ depends on everything. This may not be strictly true today -- I'd be interested in finding cases where this layering is violated and identifying whether they can be fixed or whether the layering is conceptually wrong somewhere (or if components need to be moved around).

So that's one thing to consider in terms of versioning APIs for ggp-base.

Another aspect of the layering is that player/ is really divided into player/gamer/statemachine/.../ and everything else; where the files under player/gamer/statemachine/.../ define the gaming algorithms for particular gamer implementations, whereas the rest of player/ is code that's shared between most/all players. For a developer whose only concern is making ggp-base players, maybe they only really care about that API remaining stable? (Though of course, they're likely also implementing their own state machine, which is defined in util/...)

@gsj601
Copy link
Contributor

gsj601 commented Oct 8, 2015

As a user of ggp-base (that hasn't actually contributed to ggp-base itself), I would like to +1 this (if that's okay to do without being contributing back yet...). It would be much easier for me to grab a .jar representing the part that I'm extending, than have to git-fork the entire project. Maybe I'm just doing it wrong... or could make .jar's to include myself...

A different example than building a new state machine, is building a new player and also tweaking the server, which I've had to do for my experiments. Do I force both sets of changes to be in the same git repo, when they're going to be run on different machines, keeping two separate branches that never overlap again? Or move master forward representing both sets of changes? Or do I have two whole copies of ggp-base, one with new player code, and one with new server code? Even then, it really only makes sense to checkout+edit ggp-base (i.e., fork it), if I'm actually trying to recreate or provide an alternative to the whole ggp-base project, which I don't think anyone is actually doing.

But definitely +1 to a jar per layer, too, if possible. I shouldn't need the jar to have all the app stuff and server stuff if I'm making a player.

--- Scratch that. Should have tried this before posting. I just made a jar for importing, works fine. Cut out a lot of stuff. There was, actually, an error when I took out everything from org.ggp.base.apps. Apparently, something from org.ggp.base.player that refers to org.ggp.base.apps.player? Oh well, that's a bug for a different issue. Still! +1!

@AlexLandau
Copy link
Member Author

Yes, this will be much nicer for some people, those who are experienced with software development (especially Java). If you are comfortable with using Maven, Gradle, or Ivy for dealing with dependencies, then it would become easy to put your code in a separate repo and get any updates to GGP-Base by just updating a version number. Even without a real Java build system, it's not hard to take published jars and copy them into your project.

That said, many of the people using this will be students who have some level of programming experience but know little about build systems or dependency management. For them we should keep it as easy as is reasonably possible to get started and working, just by cloning or unzipping the repo and mucking with the source files. (This is why, for example, we keep the Eclipse project files checked in instead of requiring people to generate them on the command line.) I'm not saying this to discourage these changes from happening, just as a reminder that this should be taken into account when choosing an approach.

@AlexLandau
Copy link
Member Author

I just started playing around with actually splitting this up, starting with the apps/non-apps package-level distinction, to see what goes wrong.

  1. org.ggp.base.player.proxy.* should be considered an app.
  2. The ConfigPanel and DetailPanel references in Gamer and its implementations. (Maybe have some intermediate notion of a GuiAwareGamer?)
  3. ProjectSearcher#GAME_CANVASES. This shouldn't be too hard to refactor.

@gsj601
Copy link
Contributor

gsj601 commented Oct 11, 2015

Ditto! I split apps, player, server, validator, and util into projects, repos, and jars. I think there were more issues separating util than you mentioned --- it should have no dependencies, but had panels, project searcher stuff, and I think also required RequestHandlers. But yeah, ditto.

The only problem with me doing it myself is that if I ever update by merging from ggp-base origin, files I removed from the util project/repo/jar, if changed, or added to, will probably make it hard to maintain. I originally suggested actually splitting into multiple repos, but I can see how that's a big change. But, publishing versioned jars for each of the layers would be really, really helpful, then.

@samschreiber
Copy link
Member

Actually, maybe let's start with just published versioned JARs for the
whole of ggp-base? Many of the changes that I make span layers and it'd be
a hassle to deal with version conflicts between different layer JARs every
time a cross layer change is submitted.

On Sun, Oct 11, 2015, 9:06 AM G. Scott Johnston [email protected]
wrote:

Ditto! I split apps, player, server, validator, and util into projects,
repos, and jars. I think there were more issues separating util than you
mentioned --- it should have no dependencies, but had panels, project
searcher stuff, and I think also required RequestHandlers. But yeah, ditto.

The only problem with me doing it myself is that if I ever update by
merging from ggp-base origin, files I removed from the util
project/repo/jar, if changed, or added to, will probably make it hard to
maintain. I originally suggested actually splitting into multiple repos,
but I can see how that's a big change. But, publishing versioned jars for
each of the layers would be really, really helpful, then.


Reply to this email directly or view it on GitHub
#91 (comment).

@gsj601
Copy link
Contributor

gsj601 commented Oct 11, 2015

That still would be better. As a newbie, I showed up, tried to take ggp-base and make my changes, and I wound up forking and having a huge history and having to dig in, work with gradle, and figure out where my code belonged in the package structure. Presenting a jar to use as a library makes my git history simpler, makes updates easier to fold in, and lets me run with/without gradle as I like.

@AlexLandau
Copy link
Member Author

Yeah, in terms of dividing things, I'd prefer an approach within one repo where there's only one versioning scheme involved. It would also be possible to publish both individual jars for the separate sections of the project, and a single jar that includes everything.

@AlexLandau
Copy link
Member Author

I'm continuing to try this out on the "split2" branch, with projects (so far) "gdl-core", "gdl-utils", "games", "state-machines", "propnets", "legacy", "gamers", "sample-gamers", and "apps". The "legacy" project consists of everything that hasn't been moved into one of the other projects yet. I'm trying to make this fairly fine-grained to see what the limits are, not because this is necessarily the right degree of separation.

There haven't been too many breaks resulting from this; the Pair class needs to go somewhere appropriate and GamerLogger is continuing to muck with things.

Presumably some set of these (probably the inputs to sample-gamers) would be defined as the "library" that is supported, and would be published in jar format.

@sapioit
Copy link

sapioit commented Jul 5, 2016

A better way to do versioning than Semantic Versioning is, is Explicit Versioning. Here are a few words about it (the first four words from the link basicly explaining most of it): Release.Breaking.Feature.Fix or why the Semantic Versioning should be replaced with Explicit Versioning as soon as possible

@AlexLandau
Copy link
Member Author

@sapioit: That does not seem relevant to our use case, which is a library rather than a user-facing application. The "release" version number is only relevant in the latter case.

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

No branches or pull requests

4 participants