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

Support nested vendor repositories #94

Open
thorsten-klein opened this issue Feb 19, 2021 · 1 comment
Open

Support nested vendor repositories #94

thorsten-klein opened this issue Feb 19, 2021 · 1 comment

Comments

@thorsten-klein
Copy link
Contributor

thorsten-klein commented Feb 19, 2021

Hello,
I would like to have a support for nested vendor repositories with a .braids.json file each.

e.g. I have following repositories

  • base
  • frameworkA
  • frameworkB
  • project A
  • project B

my tree is looking:

├── .braids.json
├── projectA
│   ├── .braids.json
│   └── frameworkA
│       ├── base
│       └── .braids.json
└── projectB
    ├── .braids.json
    └── frameworkB
        ├── base
        └── .braids.json

On top-level I can run braid update projectA (which is of course working), but I would also like to run it for only a nested vendor repository, e.g. braid update projectA/frameworkA or braid update projectB/frameworkB/base.

In a next step also the braid update command should support the following call:
braid update --url <url> [--branch <branch> | --tag <tag> | --revision <revision>]
e.g. braid update --url http://...base.git --branch master

This command should lead to an update of all base repositories (found recursive within all .braids.json file via given url). As a result each base repository is updated with given branch/tag/revision (in this case master branch) and also the correct .braids.json file (in which base is specified) is updated.

Is there any chance to support this?

Best Regards,
Thorsten

@mattmccutchen
Copy link
Collaborator

mattmccutchen commented Feb 20, 2021

On top-level I can run braid update projectA (which is of course working), but I would also like to run it for only a nested vendor repository, e.g. braid update projectA/frameworkA or braid update projectB/frameworkB/base.

I assume the effect of braid update projectA/frameworkA is to update your main project's nested projectA/frameworkA mirror to be based on a different revision of frameworkA than the upstream of projectA is? IIUC, this would be equivalent to running braid update frameworkA in the projectA directory as if that were the project root for Braid's purposes, but committing to the enclosing Git repository in which the worktree root is actually some ancestor directory. That shouldn't be too hard to implement: we'd just need to find all the places where Braid is depending on worktree-absolute paths and generalize them to handle a path prefix.

The harder part would be nailing down the command-line usage. If we implement #63 first, it probably wouldn't be hard to generalize it to "find the nearest ancestor .braids.json of the working directory and treat that as the project root". But if we want to support braid update projectA/frameworkA as you originally proposed or have a braid update of "all mirrors" work recursively, etc., we'll have to think harder about how to ensure all of this isn't confusing to users and potentially even consider security implications if a user accidentally operates on an untrusted .braids.json file. There's a potential alternative interpretation of braid COMMAND projectA/frameworkA, namely: "I want to have a mirror under projectA that the upstream projectA doesn't have, but I want to manage it via my root .braids.json file". I don't know if there's demand for this conceivable enhancement (we don't have an issue for it so far), but I'd be careful about foreclosing it.

I have way too long a backlog of other projects to do much more than provide friendly issue responses right now. But I think we would accept a contribution if you can convince us that the value justifies the added maintenance costs. Can you describe a complete example scenario (with specific projects and revisions) in which you'd want to use the feature?

A side note: If the following sequence of steps occurs:

  1. projectA contains a mirror based on commit X of frameworkA, and the main project contains a mirror of projectA.
  2. The main project does braid update --revision=Y projectA/frameworkA and makes some manual edits to projectA/frameworkA.
  3. Upstream projectA does braid update --revision=Y frameworkA and makes different manual edits to frameworkA.
  4. The main project does braid update projectA.

then the last step has a high risk of producing messy conflicts or even silently producing an unintended result. This is because braid update just does a three-way merge of the content of projectA and sees similar but not identical changes to frameworkA on both sides (the update from X to Y plus manual edits), so at each difference, it does not know which side has the manual edit that should be kept. (I gave a detailed example of a similar problem involving squash merges here.) I suspect this would be impractical to ever fix in Braid; the only idea I have right now for users concerned about this scenario is to use Git submodules instead. For that matter, the same problem can occur with a plain git merge of two branches of projectA, each of which has done braid update --revision=Y frameworkA and then made different manual edits to frameworkA.

In a next step also the braid update command should support the following call:add
braid update --url <url> [--branch <branch> | --tag <tag> | --revision <revision>]
e.g. braid update --url http://...base.git --branch master

This command should lead to an update of all base repositories (found recursive within all .braids.json file via given url). As a result each base repository is updated with given branch/tag/revision (in this case master branch) and also the correct .braids.json file (in which base is specified) is updated.

I'm flattered that you're interested in making such sophisticated use of Braid! But for this case, I think you're probably better off finding a real package manager with the features you need (here, coordinating versions of indirect dependencies) and then checking in the files and managing diffs on top of that. It might be possible to design a reasonable enhancement to Braid that would do the second part. If we just added the specific feature you described, I'm afraid you would just run into another missing package-manager feature that you need.

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

2 participants