Review: one local name is still a local name; a local name is unique; recovery knows it; recipes read as instructions; a tag before a digest; ask fails at once when nothing serves

A secrets object with one local name delivered no file. Two requirements could share
a local name. secret recover and the export could not tell two locals apart. The
recipe check missed continued lines and read heredoc bodies as bases. repo:tag@digest
kept the tag in the repository. ask now publishes mandatory, so a tool nothing serves
is said at once rather than after the wait.
This commit is contained in:
2026-09-21 21:03:22 +02:00
parent e81f352979
commit 9f3790dcda
13 changed files with 229 additions and 29 deletions
+9 -2
View File
@@ -1050,6 +1050,7 @@ func ParseManifest(raw []byte) (Manifest, error) {
problems = append(problems, m.Module+" needs a secret with no name")
}
}
localOf := map[string]string{}
for _, to := range m.SecretRequirements() {
if _, plain := m.Secrets[to]; plain {
if _, also := m.SecretsMany[to]; also {
@@ -1069,9 +1070,15 @@ func ParseManifest(raw []byte) (Manifest, error) {
m.Module, to, f.Local))
}
// A local name is what `${secret:<name>}` says, so it may not be another requirement's
// name or one of the module's own secrets — the file would hold the wrong credential
// while every check passed.
// name, another requirement's local name, or one of the module's own secrets — the
// file would hold the wrong credential while every check passed.
if f.Local != "" {
if other, taken := localOf[f.Local]; taken && other != to {
problems = append(problems, fmt.Sprintf(
"%s keeps credentials for %q and %q both under %q — a local name names one",
m.Module, other, to, f.Local))
}
localOf[f.Local] = to
if _, own := m.OwnSecrets[f.Local]; own {
problems = append(problems, fmt.Sprintf(
"%s keeps a credential for %q under %q, which is also one of its own secrets",