1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
|
package archive
import (
"context"
"errors"
"fmt"
"io"
"os"
)
var (
// ErrUnsupportedArchiveFormat is returned if an archiver or extractor format
// requested has not been registered.
ErrUnsupportedArchiveFormat = errors.New("unsupported archive format")
)
// CompressionLevel type for specifying a compression level.
type CompressionLevel int
// Compression levels from fastest (low/zero compression ratio) to slowest
// (high compression ratio).
const (
FastestCompression CompressionLevel = -2
FastCompression CompressionLevel = -1
DefaultCompression CompressionLevel = 0
SlowCompression CompressionLevel = 1
SlowestCompression CompressionLevel = 2
)
// Format type for specifying format.
type Format string
// Formats supported by GitLab.
const (
Raw Format = "raw"
Gzip Format = "gzip"
Zip Format = "zip"
)
var (
archivers = make(map[Format]NewArchiverFunc)
extractors = make(map[Format]NewExtractorFunc)
)
// Archiver is an interface for the Archive method.
type Archiver interface {
Archive(ctx context.Context, files map[string]os.FileInfo) error
}
// Extractor is an interface for the Extract method.
type Extractor interface {
Extract(ctx context.Context) error
}
// NewArchiverFunc is a function that can be registered (with Register()) and
// used to instantiate a new archiver (with NewArchiver()).
type NewArchiverFunc func(w io.Writer, dir string, level CompressionLevel) (Archiver, error)
// NewExtractorFunc is a function that can be registered (with Register()) and
// used to instantiate a new extractor (with NewExtractor()).
type NewExtractorFunc func(r io.ReaderAt, size int64, dir string) (Extractor, error)
// Register registers a new archiver, overriding the archiver and/or extractor
// for the format provided.
func Register(format Format, archiver NewArchiverFunc, extractor NewExtractorFunc) {
if archiver != nil {
archivers[format] = archiver
}
if extractor != nil {
extractors[format] = extractor
}
}
// NewArchiver returns a new Archiver of the specified format.
//
// The archiver will ensure that files to be archived are children of the
// directory provided.
func NewArchiver(format Format, w io.Writer, dir string, level CompressionLevel) (Archiver, error) {
fn := archivers[format]
if fn == nil {
return nil, fmt.Errorf("%q format: %w", format, ErrUnsupportedArchiveFormat)
}
return fn(w, dir, level)
}
// NewExtractor returns a new Extractor of the specified format.
//
// The extractor will extract files to the directory provided.
func NewExtractor(format Format, r io.ReaderAt, size int64, dir string) (Extractor, error) {
fn := extractors[format]
if fn == nil {
return nil, fmt.Errorf("%q format: %w", format, ErrUnsupportedArchiveFormat)
}
return fn(r, size, dir)
}
|