Skip to content

Commit

Permalink
fix: migrate mholt/archiver/v3 to mholt/archives (#3422)
Browse files Browse the repository at this point in the history
* fix: migrate mholt/archiver/v3 to mholt/archives

* refactor: remove unused codes

* fix(unarchive): support decompressor

* ci: test unarchive

* chore: go mod tidy

* fix(unarchive): exit soon after unarchiving

* refactor: remove unused files

* refactor: fix lint errors

* ci: fix test data

* fix: comment out skip link

* fix(unarchive): detect file path separator automatically

* refactor: fix a lint error

* fix(unarchive): continue the process even if it fails to unarchive some files

* fix(unarchive): add 0o700 permission to directories

* refactor: ignore a lint error

* chore(go): go mod tidy

---------

Co-authored-by: aquaproj-aqua-releaser[bot] <95135029+aquaproj-aqua-releaser[bot]@users.noreply.github.com>
  • Loading branch information
1 parent 9acb4eb commit 327e58f
Show file tree
Hide file tree
Showing 9 changed files with 472 additions and 239 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/wc-integration-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ jobs:
- name: Test g -g
run: aqua g -g cli/cli

- name: Test unarchive
run: aqua i
working-directory: tests/unarchive

- name: Test checksum
run: aqua -c aqua.yaml i
working-directory: tests/3064
Expand Down
32 changes: 20 additions & 12 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ require (
github.com/invopop/jsonschema v0.13.0
github.com/ktr0731/go-fuzzyfinder v0.8.0
github.com/mattn/go-colorable v0.1.13
github.com/mholt/archiver/v3 v3.5.1
github.com/mholt/archives v0.1.0
github.com/otiai10/copy v1.14.1
github.com/schollz/progressbar/v3 v3.14.2
github.com/sirupsen/logrus v1.9.3
Expand All @@ -38,20 +38,26 @@ require (
dario.cat/mergo v1.0.1 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.3.0 // indirect
github.com/andybalholm/brotli v1.0.1 // indirect
github.com/STARRY-S/zip v0.2.1 // indirect
github.com/andybalholm/brotli v1.1.1 // indirect
github.com/bahlo/generic-list-go v0.2.0 // indirect
github.com/bodgit/plumbing v1.3.0 // indirect
github.com/bodgit/sevenzip v1.6.0 // indirect
github.com/bodgit/windows v1.0.1 // indirect
github.com/buger/jsonparser v1.1.1 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 // indirect
github.com/gdamore/encoding v1.0.0 // indirect
github.com/gdamore/tcell/v2 v2.6.0 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/huandu/xstrings v1.5.0 // indirect
github.com/klauspost/compress v1.15.11 // indirect
github.com/klauspost/pgzip v1.2.5 // indirect
github.com/klauspost/compress v1.17.11 // indirect
github.com/klauspost/pgzip v1.2.6 // indirect
github.com/ktr0731/go-ansisgr v0.1.0 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
Expand All @@ -61,23 +67,25 @@ require (
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/nsf/termbox-go v1.1.1 // indirect
github.com/nwaples/rardecode v1.1.0 // indirect
github.com/nwaples/rardecode/v2 v2.0.0-beta.4.0.20241112120701-034e449c6e78 // indirect
github.com/otiai10/mint v1.6.3 // indirect
github.com/pierrec/lz4/v4 v4.1.2 // indirect
github.com/pierrec/lz4/v4 v4.1.21 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
github.com/sorairolake/lzip-go v0.3.5 // indirect
github.com/spf13/cast v1.7.0 // indirect
github.com/stretchr/testify v1.9.0 // indirect
github.com/suzuki-shunsuke/go-jsoneq v0.1.2 // indirect
github.com/ulikunitz/xz v0.5.10 // indirect
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
github.com/therootcompany/xz v1.0.1 // indirect
github.com/ulikunitz/xz v0.5.12 // indirect
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
go4.org v0.0.0-20230225012048-214862532bf5 // indirect
golang.org/x/crypto v0.28.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sync v0.9.0 // indirect
golang.org/x/term v0.25.0 // indirect
golang.org/x/text v0.19.0 // indirect
golang.org/x/text v0.20.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
)
275 changes: 248 additions & 27 deletions go.sum

Large diffs are not rendered by default.

129 changes: 129 additions & 0 deletions pkg/unarchive/archives.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package unarchive

import (
"context"
"fmt"
"io"
"os"
"path/filepath"
"strings"

"github.com/aquaproj/aqua/v2/pkg/osfile"
"github.com/mholt/archives"
"github.com/sirupsen/logrus"
"github.com/spf13/afero"
"github.com/suzuki-shunsuke/logrus-error/logerr"
)

type handler struct {
fs afero.Fs
dest string
filename string
logE *logrus.Entry
}

func (h *handler) normalizePath(nameInArchive string) string {
slashCount := strings.Count(nameInArchive, "/")
backSlashCount := strings.Count(nameInArchive, "\\")
if backSlashCount > slashCount && filepath.Separator != '\\' {
return strings.ReplaceAll(nameInArchive, "\\", string(filepath.Separator))
}
return nameInArchive
}

func (h *handler) HandleFile(_ context.Context, f archives.FileInfo) error {
dstPath := filepath.Join(h.dest, h.normalizePath(f.NameInArchive))
parentDir := filepath.Dir(dstPath)
if err := osfile.MkdirAll(h.fs, parentDir); err != nil {
logerr.WithError(h.logE, err).Warn("create a directory")
return nil
}

if f.IsDir() {
if err := h.fs.MkdirAll(dstPath, f.Mode()|0o700); err != nil { //nolint:mnd
logerr.WithError(h.logE, err).Warn("create a directory")
return nil
}
return nil
}

// if f.LinkTarget != "" {
// return nil
// }

reader, err := f.Open()
if err != nil {
logerr.WithError(h.logE, err).Warn("open a file")
return nil
}
defer reader.Close()

dstFile, err := h.fs.OpenFile(dstPath, os.O_CREATE|os.O_WRONLY, f.Mode())
if err != nil {
logerr.WithError(h.logE, err).Warn("create a file")
return nil
}
defer dstFile.Close()

if _, err := io.Copy(dstFile, reader); err != nil {
logerr.WithError(h.logE, err).Warn("copy a file")
return nil
}
return nil
}

func (h *handler) Unarchive(ctx context.Context, _ *logrus.Entry, src *File) error {
tempFilePath, err := src.Body.Path()
if err != nil {
return fmt.Errorf("get a temporary file path: %w", err)
}
return h.unarchive(ctx, tempFilePath)
}

func (h *handler) unarchive(ctx context.Context, file string) error {
archiveFile, err := h.fs.Open(file)
if err != nil {
return fmt.Errorf("open a files: %w", err)
}
defer archiveFile.Close()

format, input, err := archives.Identify(ctx, file, archiveFile)
if err != nil {
return fmt.Errorf("identify the format: %w", err)
}

if extractor, ok := format.(archives.Extractor); ok {
if err := osfile.MkdirAll(h.fs, h.dest); err != nil {
return fmt.Errorf("create a destination directory: %w", err)
}

if err := extractor.Extract(ctx, input, h.HandleFile); err != nil {
return fmt.Errorf("extract files: %w", err)
}
return nil
}
if decomp, ok := format.(archives.Decompressor); ok {
return h.decompress(input, decomp)
}
return errUnsupportedFileFormat
}

func (h *handler) decompress(input io.Reader, decomp archives.Decompressor) error {
rc, err := decomp.OpenReader(input)
if err != nil {
return fmt.Errorf("open a decompressed file: %w", err)
}
defer rc.Close()
if err := osfile.MkdirAll(h.fs, h.dest); err != nil {
return fmt.Errorf("create a directory (%s): %w", h.dest, err)
}
dst, err := h.fs.Create(filepath.Join(h.dest, strings.TrimSuffix(h.filename, filepath.Ext(h.filename))))
if err != nil {
return fmt.Errorf("create a destination file: %w", err)
}
defer dst.Close()
if _, err := io.Copy(dst, rc); err != nil {
return fmt.Errorf("copy decompressed data: %w", err)
}
return nil
}
38 changes: 0 additions & 38 deletions pkg/unarchive/decompressor.go

This file was deleted.

75 changes: 22 additions & 53 deletions pkg/unarchive/unarchive.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,9 @@ package unarchive
import (
"context"
"errors"
"fmt"
"io"
"path/filepath"
"strings"

"github.com/mholt/archiver/v3"
"github.com/sirupsen/logrus"
"github.com/spf13/afero"
)
Expand Down Expand Up @@ -44,12 +41,7 @@ func New(executor Executor, fs afero.Fs) *Unarchiver {
}

func (u *Unarchiver) Unarchive(ctx context.Context, logE *logrus.Entry, src *File, dest string) error {
arc, err := u.getUnarchiver(src, dest)
if err != nil {
return fmt.Errorf("get the unarchiver or decompressor by the file extension: %w", err)
}

return arc.Unarchive(ctx, logE, src) //nolint:wrapcheck
return u.getUnarchiver(src, dest).Unarchive(ctx, logE, src) //nolint:wrapcheck
}

func IsUnarchived(archiveType, assetName string) bool {
Expand All @@ -63,69 +55,46 @@ func IsUnarchived(archiveType, assetName string) bool {
return ext == "" || ext == ".exe"
}

func (u *Unarchiver) getUnarchiver(src *File, dest string) (coreUnarchiver, error) {
func (u *Unarchiver) getUnarchiver(src *File, dest string) coreUnarchiver {
filename := filepath.Base(src.Filename)
if IsUnarchived(src.Type, filename) {
return &rawUnarchiver{
dest: filepath.Join(dest, filename),
fs: u.fs,
}, nil
}
}
if src.Type == "dmg" {
return &dmgUnarchiver{
dest: dest,
executor: u.executor,
fs: u.fs,
}, nil
}
}
if src.Type == "pkg" {
return &pkgUnarchiver{
dest: dest,
executor: u.executor,
fs: u.fs,
}, nil
}

f := filename
if src.Type != "" {
f = "." + src.Type
}
arc, err := byExtension(f)
if err != nil {
return nil, fmt.Errorf("get the unarchiver or decompressor by the file extension: %w", err)
}
}

switch t := arc.(type) {
case archiver.Unarchiver:
return &unarchiverWithUnarchiver{
unarchiver: t,
dest: dest,
fs: u.fs,
}, nil
case archiver.Decompressor:
return &Decompressor{
decompressor: t,
dest: filepath.Join(dest, strings.TrimSuffix(filename, filepath.Ext(filename))),
fs: u.fs,
}, nil
switch ext := filepath.Ext(filename); ext {
case ".dmg":
return &dmgUnarchiver{
dest: dest,
executor: u.executor,
fs: u.fs,
}
case ".pkg":
return &pkgUnarchiver{
dest: dest,
executor: u.executor,
fs: u.fs,
}
}
return nil, errUnsupportedFileFormat
}

func byExtension(filename string) (interface{}, error) {
formats := map[string]interface{}{
"tbr": archiver.NewTarBrotli(),
"tbz": archiver.NewTarBz2(),
"tbz2": archiver.NewTarBz2(),
"tgz": archiver.NewTarGz(),
"tlz4": archiver.NewTarLz4(),
"tsz": archiver.NewTarSz(),
"txz": archiver.NewTarXz(),
}
for format, arc := range formats {
if strings.HasSuffix(filename, "."+format) {
return arc, nil
}
return &handler{
fs: u.fs,
dest: dest,
filename: filename,
}
return archiver.ByExtension(filename) //nolint:wrapcheck
}
Loading

0 comments on commit 327e58f

Please sign in to comment.