TriBITS
TriBITS copied to clipboard
gitdist: Add dist-foreach command
The basic usage of the gitdist command:
$ gitdist [gitdist options] <raw-git-command> [git command options]
works well for many workflows. However, there are some operations where one needs to ability to run arbitrary commands over each of the git repos. This feature is supported by the Google Repo tool using the command repo forall -c <command> and by the git submodule command git submodule foreach '<command>'.
This story is to implement a new gitdist command called dist-foreach (alias gitdist-foreach) that works similar git submodule foreach ‘<command>’ (with env vars $name, $path, $toplevel, $sha1) and the Google Repo script ‘forall’ command.
One issue to consider is how to pass in info specific for each repo. The git submodule foreach command says that it defines the env vars $name, $path, $toplevel, $sha1. So to use these, you would need to quote the entire command (so that the shell does not try to evaluate those in the outer invocation of git submodule foreach). The Google Repo script's forall command also defines env vars but with names REPO_PROJECT, REPO_PATH, REPO_REMOTE, REPO_LREV, REPO_RREV, REPO_COUNT, and REPO_I. I think that it would have the same issue (i.e. needing to quote the entire sub-command).
The approach that I might take with gitdist is to define the place-holder variables _REPO_NAME_, _REPO_PATH_, _REPO_TOPLEVEL_, _REPO_SHA1_, _REPO_BRANCH_, _REPO_REMOTE_ and _REPO_REMOTE_BRANCH_ which would do whole identifier replacements only, like the _VERSION_ variable currently does with the --dist-version-file=<filename> argument. But to support more general nested scripts, the gitdist script could also set the env vars REPO_NAME, REPO_PATH, REPO_TOPLEVEL, REPO_SHA1, REPO_BRANCH, REPO_REMOTE and REPO_REMOTE_BRANCH. It would also be useful if these variables were also token replaced in the basic gitdist <raw-git-command> [git options] usage as well. With that you could set up a new remote like is often done for CASL VERA development:
$ gitdist remote add collab git@casl-dev:collaboration/_REPO_NAME_.git
$ gitdist remote -v | grep "(Repo:|fetch)"
$ gitdist fetch collab
But the more general dist-foreach command is needed for use cases like:
$ gitdist --dist-abort-on-fail dist-foreach <some-base-dir>/merge-develop-to-master.sh
as mentioned in #133. But note that latter use case does not need any extra variables.
Tasks:
- Implement basic
dist-foreachcommand but without any variable substitution. - Add variable substitution for
_REPO_NAME_,_REPO_PATH_,_REPO_TOPLEVEL_,_REPO_SHA1_,_REPO_BRANCH_,_REPO_REMOTE_and_REPO_REMOTE_BRANCH_and their env var counterparts.
The tool gitslave:
- https://github.com/joelpurra/gitslave
also does substitution (see the section SUBSTITUTION), except it does substitutions using %%<var-name>%%. That would be less likely to be substituted incorrectly than _<var-name>_. That means that I should instead define:
%%toplevel%%: Absolute path of the base directory where the .gitdist file is defined%%relpath%%: Relative path to the git repo being processed w.r.t. the base-level%%toplevel%%directory%%basename%%: Base name of the repo path (last component of the path%%path%%). This is typically the name of the git repo on the remote.%%sha1%%: SHA1 being pointed to byHEAD%%version%%: The SHA1 read out of the--dist-version-file=<file1>.%%version2%%: The SHA1 read out of the--dist-version-file2=<file2>.%%branch%%: Local branch name of the repo (if on a branch, otherwise empty '').%%trackingbranch%%: The name of the tracking branch in the form<remote>/<remotebranch>(if no tracking branch exists, then is empty '').
Then we should just do away with _VERSION_ and people should use %%version%%.
We should also create env vars of the same name as those above to be used as $toplevel, $relpath, $basename, $sha1, $version, $version2, $branch, and $trackingbranch in scripts with the dist-foreach command.
This allows operations like creating the collaboration remotes for CASL VERA like:
$ gitdist remote add collab git@casl-dev:collaboration/%%basename%%.git
$ gitdist fetch collab
The gitslave tool only supports substitution and Google Repo forall and git submoudle foreach only support env vars. With this, gitdist would support both so users could choose.