fix(cli): warn when publishing a repo that contains submodules
`git archive` does not recurse into submodules, so a plugin shipping vendored code via submodule produced a tarball where the submodule path existed but was empty — silent failure. Now publish reads .gitmodules and lists submodule paths to stderr with guidance to vendor or pack them separately. The publish still proceeds, since the developer may not actually need the submodule contents in the archive. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
c3cfa18ae0
commit
137a50c932
@ -325,6 +325,18 @@ func newPluginPublishCmd() *cobra.Command {
|
|||||||
fmt.Fprintln(os.Stderr, " (run `git rm --cached <file>` to drop)")
|
fmt.Fprintln(os.Stderr, " (run `git rm --cached <file>` to drop)")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// `git archive` does not recurse into submodules, so any submodule
|
||||||
|
// paths will appear as empty directories in the tarball. Detect via
|
||||||
|
// .gitmodules so this works even for submodules that haven't been
|
||||||
|
// initialised yet.
|
||||||
|
if paths := submodulePaths("."); len(paths) > 0 {
|
||||||
|
fmt.Fprintln(os.Stderr, "warning: this repo has submodules; git archive will ship them as empty directories:")
|
||||||
|
for _, p := range paths {
|
||||||
|
fmt.Fprintln(os.Stderr, " "+p)
|
||||||
|
}
|
||||||
|
fmt.Fprintln(os.Stderr, " (vendor the contents or pack them separately if the plugin depends on them)")
|
||||||
|
}
|
||||||
|
|
||||||
archiveBytes, err := archive.BuildSourceArchive(".")
|
archiveBytes, err := archive.BuildSourceArchive(".")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("build archive: %w", err)
|
return fmt.Errorf("build archive: %w", err)
|
||||||
@ -577,6 +589,27 @@ func checkRepoHasHEAD(repoDir string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// submodulePaths returns the configured submodule paths from .gitmodules.
|
||||||
|
// Reading the file directly (rather than running `git submodule status`) means
|
||||||
|
// we detect submodules that have been declared but not yet initialised.
|
||||||
|
func submodulePaths(repoDir string) []string {
|
||||||
|
cmd := exec.Command("git", "config", "--file", ".gitmodules", "--get-regexp", `submodule\..*\.path`)
|
||||||
|
cmd.Dir = repoDir
|
||||||
|
out, err := cmd.Output()
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var paths []string
|
||||||
|
for _, line := range strings.Split(strings.TrimSpace(string(out)), "\n") {
|
||||||
|
// each line is "submodule.<name>.path <path>"
|
||||||
|
fields := strings.Fields(line)
|
||||||
|
if len(fields) >= 2 {
|
||||||
|
paths = append(paths, fields[len(fields)-1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return paths
|
||||||
|
}
|
||||||
|
|
||||||
func upsertPluginMod(scope, name, kind string, categories []string) error {
|
func upsertPluginMod(scope, name, kind string, categories []string) error {
|
||||||
const file = "plugin.mod"
|
const file = "plugin.mod"
|
||||||
existing, _ := os.ReadFile(file)
|
existing, _ := os.ReadFile(file)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user