Skip to content

Commit

Permalink
fix: include parent dirs when listing archive members
Browse files Browse the repository at this point in the history
Zip archives can omit files' parent directories, as they will be
automatically created during extraction. When listing members from
a zip archive, ensure that all parent directories are included. This
guarantees that during charm cleanup, directories are not missed.
  • Loading branch information
weiiwang01 committed Jul 15, 2024
1 parent c09ff56 commit 237f6eb
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
11 changes: 10 additions & 1 deletion charmarchive.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,16 @@ func (a *CharmArchive) ArchiveMembers() (set.Strings, error) {
if err != nil {
return set.NewStrings(), err
}
manifest := set.NewStrings(paths...)
manifest := set.NewStrings()
// Zip archives can omit file's parent directories,
// as these are created automatically during extraction.
// Ensure that parent directories exist in the member list.
for _, path := range paths {
for path != "." && path != "/" {
manifest.Add(path)
path = filepath.Dir(path)
}
}
// We always write out a revision file, even if there isn't one in the
// archive; and we always strip ".", because that's sometimes not present.
manifest.Add("revision")
Expand Down
44 changes: 44 additions & 0 deletions charmarchive_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"archive/zip"
"bytes"
"fmt"
"io"
"io/ioutil"
"os"
"os/exec"
Expand Down Expand Up @@ -221,6 +222,14 @@ func (s *CharmArchiveSuite) TestArchiveMembersSymlink(c *gc.C) {
c.Assert(manifest, gc.DeepEquals, set.NewStrings(expected...))
}

func (s *CharmArchiveSuite) TestArchiveMembersOmitDirs(c *gc.C) {
srcPath := cloneDir(c, charmDirPath(c, "dummy"))
archive := archiveDirOnlyFiles(c, srcPath)
manifest, err := archive.ArchiveMembers()
c.Assert(err, gc.IsNil)
c.Assert(manifest, gc.DeepEquals, set.NewStrings(dummyArchiveMembers...))
}

func (s *CharmArchiveSuite) TestExpandTo(c *gc.C) {
archive, err := charm.ReadCharmArchive(s.archivePath)
c.Assert(err, gc.IsNil)
Expand Down Expand Up @@ -475,3 +484,38 @@ func archiveDir(c *gc.C, dirpath string) *charm.CharmArchive {
c.Assert(err, gc.IsNil)
return archive
}

func archiveDirOnlyFiles(c *gc.C, dirpath string) *charm.CharmArchive {
dir, err := charm.ReadCharmDir(dirpath)
c.Assert(err, gc.IsNil)
buf := new(bytes.Buffer)
err = dir.ArchiveTo(buf)
r, err := zip.NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
c.Assert(err, gc.IsNil)
buf = new(bytes.Buffer)
w := zip.NewWriter(buf)
for _, f := range r.File {
if f.FileInfo().IsDir() {
continue
}
rf, err := f.Open()
if err != nil {
c.Assert(err, gc.IsNil)
}
wf, err := w.Create(f.Name)
if err != nil {
c.Assert(err, gc.IsNil)
}
_, err = io.Copy(wf, rf)
if err != nil {
c.Assert(err, gc.IsNil)
}
}
err = w.Close()
if err != nil {
c.Assert(err, gc.IsNil)
}
archive, err := charm.ReadCharmArchiveBytes(buf.Bytes())
c.Assert(err, gc.IsNil)
return archive
}

0 comments on commit 237f6eb

Please sign in to comment.