Hello all, ### TLDR
Repo version tracking is somewhat broken due to a single feature (commit versions). To solve this, I propose that: 1. We remove the concept of version.yml files 2. Commit versions now conflict with ALL other versions. I'll try to distill my thoughts into something readable below. ### DEFINITIONS REPO DEPENDENCY (dep): A dependency on a specific version of a Mynewt repo. FIXED VERSION: An exact repo version number. Examples: 1.0.1 2.0.0 FLOATING VERSION: A partial repo version number with a "stability specifier". Examples: 1-latest # (1.x.x) 0-dev # (0.x.x) 1.1-latest # (1.1.x) COMMIT VERSION: Points to a git object (branch/tag/hash) of a repo. Uses the "commit" stability specifier. Examples: 7088a7c029b5cc48efa079f5b6bb25e4a5414d24-commit mynewt_1_7_0_tag-commit master-commit ROOT DEPENDENCY (ROOTDEP): A repo dependency expressed in `project.yml` INTER DEPENDENCY (INTERDEP): A dependency of one repo on another. These are expressed in the depending repo's `repository.yml` file. ### CURRENT IMPLEMENTATION When the user runs `newt upgrade`, the newt tool calculates which git hash to check out for each repo. The process goes like this: 1. Start with an empty working set of deps. 2. Add all rootdeps to the working set. 3. For each unvisited dep `d` in the working set: a. Add all of d's interdeps to the working set. 4. Repeat step 3 until all deps have been visited. I think that procedure is pretty simple and straightforward (if a little tedious to read). Things get weird in the process that follows: conflict detection. A "conflict" is when the working set contains more than one version of the same repo. In other words, someone wants version X while someone else wants version Y. Newt can only check out a single version of a given repo, so it reports a conflict and aborts the upgrade. So far, this probably sounds reasonable. Unfortunately, the process gets really convoluted due to commit versions. Commit versions are problematic because they aren't linked to a version numbers. For example, repo R has a tag defining version 1.2.0. What version number should be assigned to the parent commit of this tag? What about commits on their own branches? The way newt solves this is by requiring a `version.yml` file in each repo. This file contains a single fixed version. To determine the version of a particular commit, newt checks out that commit and reads the contents of `version.yml`. When a maintainer releases a new version of a repo, they have to update `version.yml` before creating the tag. I think this version.yml idea was a mistake. The entire reason this idea was introduced was to make it possible to gauge compatibility when commit versions are used. But that motivation is itself flawed; the notion of "compatibility" is not valid when dealing with commit versions because arbitrary commits don't come with any compatibility guarantees. Secondary problems with the `version.yml` idea is that it is error prone and requires extra work for a Mynewt repo maintainer. ### PROPOSAL 1. No more version.yml files. 2. Commit versions conflict with ALL other versions. In other words, newt doesn't try to figure out what a commit version's "real version number" is. One way to think of it is: each commit version has its own unique version number. As a consequence, different commit versions always conflict with each other. I should also mention that newt allows the `project.yml` file to override any interdep with a commit version rootdep. Newt accepts the rootdep and does not report a conflict. All comments welcome. Thanks, Chris