gitea: stop a real npm retention when a file was not read whole
A lockfile that could not be read is one of its repository's files that could not be read (hq ADR 0251 §4): a version only it pins would be deleted while in use. A real run now refuses on files_not_read as it does on repositories_unread; a dry run still reports.
This commit is contained in:
@@ -395,8 +395,8 @@ func retention(ctx context.Context, f *Forge, only string, keep int, dryRun bool
|
||||
s.Repositories, countVersions(s), len(s.Packages), mib(p.RegistryBytes), len(p.Candidates), mib(p.Bytes)))
|
||||
s.Said = append(s.Said, sizesSaid(s)...)
|
||||
if len(s.NotRead) > 0 {
|
||||
s.Said = append(s.Said, fmt.Sprintf("%d files were not read whole (files_not_read): a version only they name is "+
|
||||
"kept by nothing here", len(s.NotRead)))
|
||||
s.Said = append(s.Said, fmt.Sprintf("%d files were not read whole (files_not_read): what they name is not "+
|
||||
"known, so a real run deletes nothing", len(s.NotRead)))
|
||||
}
|
||||
if len(s.Unread) > 0 {
|
||||
s.Said = append(s.Said, fmt.Sprintf("%d repositories or files could not be read: what they depend on is not "+
|
||||
@@ -410,6 +410,12 @@ func retention(ctx context.Context, f *Forge, only string, keep int, dryRun bool
|
||||
return p, fmt.Errorf("refused: %d repositories or files could not be read, so what depends on what is not "+
|
||||
"known; nothing was deleted (first: %s)", len(s.Unread), s.Unread[0])
|
||||
}
|
||||
// A file that was fetched but not read whole is a file of its repository that could not be read
|
||||
// (novox/hq ADR 0251 §4): a version only it names would be deleted while in use.
|
||||
if len(s.NotRead) > 0 {
|
||||
return p, fmt.Errorf("refused: %d files were not read whole, so what they name is not known; nothing was "+
|
||||
"deleted (first: %s)", len(s.NotRead), s.NotRead[0])
|
||||
}
|
||||
del, cancel := context.WithTimeout(context.Background(), budget)
|
||||
defer cancel()
|
||||
for _, c := range p.Candidates {
|
||||
|
||||
@@ -465,3 +465,26 @@ func TestALockfileOfEveryShapeKeepsWhatItPins(t *testing.T) {
|
||||
t.Fatalf("0.2.0: %+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnUnreadableLockfileStopsARealRunBeforeAnythingIsDeleted(t *testing.T) {
|
||||
f := aRegistry(t)
|
||||
f.repos["acme/odd"] = map[string]string{"package-lock.json": `{"lockfileVersion":3,"packages":{`}
|
||||
p, err := retention(context.Background(), f.serve(), "", 3, false, "tidy")
|
||||
if err == nil || !strings.Contains(err.Error(), "nothing was deleted") || !strings.Contains(err.Error(), "acme/odd:package-lock.json") {
|
||||
t.Fatalf("got %v", err)
|
||||
}
|
||||
if len(f.deleted) != 0 {
|
||||
t.Fatalf("deleted %v while a lockfile was not read", f.deleted)
|
||||
}
|
||||
if p == nil || len(p.NotRead) != 1 || len(p.Deleted) != 0 {
|
||||
t.Fatalf("plan %+v", p)
|
||||
}
|
||||
// And the dry run says so, without failing, and still says what would go.
|
||||
dry, err := retention(context.Background(), f.serve(), "", 3, true, "")
|
||||
if err != nil || len(dry.NotRead) != 1 || len(dry.Candidates) == 0 {
|
||||
t.Fatalf("dry run: %v %+v", err, dry)
|
||||
}
|
||||
if !strings.Contains(strings.Join(dry.Said, "\n"), "1 files were not read whole") {
|
||||
t.Errorf("said %v", dry.Said)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user