fix(34): CR-02 install plugins of an installed module at its version
plugin:install pinned only modules chosen in the same plan, so a second plugin package in a module the application already required was installed at the newest release, moving the plugin already there, and with --source the repository was cloned a second time. PlanInstall now seeds every module of summer.yaml: a plugin in one installs at the installed version with no go get or clone (only its summer.yaml entry), and is refused with a plugin:update hint when that version has no release of it or is not a release. A git URL whose repository is already a submodule, or whose module the application has, is refused.
This commit is contained in:
@@ -230,6 +230,11 @@ func (in *installer) planGitURL(rawURL string) error {
|
||||
if err := requireGitRepo(in.ctx, in.appDir); err != nil {
|
||||
return err
|
||||
}
|
||||
if dir := submoduleWithURL(in.ctx, in.appDir, rawURL); dir != "" {
|
||||
return bonfire.WithHint(fmt.Errorf("build: %s is already checked out at %s", rawURL, dir),
|
||||
"plugin:install does not clone a repository the application already has as a submodule. Update the plugins in it with plugin:update.",
|
||||
"{bin} plugin:update")
|
||||
}
|
||||
fmt.Fprintf(in.out, "Cloning %s\n", rawURL)
|
||||
tmp, err := cloneInto(in.ctx, in.appDir, rawURL, in.opts.Interactive)
|
||||
if err != nil {
|
||||
@@ -306,6 +311,11 @@ func (in *installer) planGitURL(rawURL string) error {
|
||||
if err := validateStep(step); err != nil {
|
||||
return err
|
||||
}
|
||||
if im, ok := in.installed[step.Module]; ok {
|
||||
return bonfire.WithHint(fmt.Errorf("build: %s is module %s, which the application already has (for %s)", rawURL, step.Module, im.by),
|
||||
"plugin:install does not move plugins the application already has, and a second checkout of one module breaks the workspace. Update the module with plugin:update.",
|
||||
"{bin} plugin:update "+im.by)
|
||||
}
|
||||
if _, err := submoduleTarget(in.ctx, in.appDir, tmp, step.ID, rawURL); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -320,6 +330,31 @@ func (in *installer) planGitURL(rawURL string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// submoduleWithURL returns the path of the application's submodule whose
|
||||
// .gitmodules URL is rawURL (ignoring a trailing slash or .git), or "".
|
||||
func submoduleWithURL(ctx context.Context, appDir, rawURL string) string {
|
||||
out, err := gitOutput(ctx, appDir, "config", "--file", ".gitmodules", "--get-regexp", `^submodule\..*\.url$`)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
norm := func(u string) string {
|
||||
return strings.TrimSuffix(strings.TrimRight(u, "/"), ".git")
|
||||
}
|
||||
want := norm(rawURL)
|
||||
for _, line := range strings.Split(strings.TrimSpace(string(out)), "\n") {
|
||||
key, val, ok := strings.Cut(line, " ")
|
||||
if !ok || norm(strings.TrimSpace(val)) != want {
|
||||
continue
|
||||
}
|
||||
name := strings.TrimSuffix(strings.TrimPrefix(key, "submodule."), ".url")
|
||||
if p, err := gitOutput(ctx, appDir, "config", "--file", ".gitmodules", "submodule."+name+".path"); err == nil {
|
||||
return strings.TrimSpace(string(p))
|
||||
}
|
||||
return name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// readCheckoutManifest reads <dir>/<rel>/plugin.yaml from a work tree; nil
|
||||
// when it does not exist.
|
||||
func readCheckoutManifest(dir, rel string) (*kiosk.Manifest, error) {
|
||||
|
||||
Reference in New Issue
Block a user