Compare commits

...

4 commits
v0.1.0 ... main

Author SHA1 Message Date
72721eddcd
update readme 2024-12-12 10:08:49 -05:00
7fc67a10c9
transfer repo, remove retractions 2024-12-09 08:10:12 -05:00
4eb6158348
add retract directive in go mod 2024-12-08 21:05:15 -05:00
6f66040e09
Add ExtractFile function 2024-12-08 20:50:43 -05:00
5 changed files with 87 additions and 2 deletions

View file

@ -8,7 +8,7 @@ The whole goal with this library is to create something that can both read and w
## Roadmap ## Roadmap
- [x] Automatically detect the archive format - [x] Automatically detect the archive format
- [x] Add mutexes to work with concurrency - [x] Add mutexes to work with concurrency
- [ ] Support RAR format - [ ] Support RAR format (will be read-only)
- [ ] Support zstd format - [ ] Support zstd format
- [ ] Add writing capability - [ ] Add writing capability
- [ ] Support multithreaded gzip - [ ] Support multithreaded gzip

View file

@ -141,6 +141,17 @@ func (a *Archive) Extract(opts ExtractOptions) error {
return extract(Filesystem{file: true}, opts, a) return extract(Filesystem{file: true}, opts, a)
} }
// ExtractFile extracts a specified file from an archive to a specified directory.
// It takes a file path, and ExtractFileOptions as its parameters.
// The function returns an error, if any.
func (a *Archive) ExtractFile(path string, opts ExtractFileOptions) error {
file, err := a.GetFile(path)
if err != nil {
return err
}
return file.Extract(opts)
}
// Close closes the Archive. // Close closes the Archive.
// The function returns an error, if any. // The function returns an error, if any.
func (a *Archive) Close() error { func (a *Archive) Close() error {

View file

@ -92,30 +92,80 @@ func TestArchiveExtract(t *testing.T) {
}) })
assert.NoError(t, err) assert.NoError(t, err)
err = os.RemoveAll(testArchiveBaseDir + "/extracted/zip")
assert.NoError(t, err)
t.Log("== ExtractFileZip ==")
err = ExtractFile(testArchiveBaseDir+"/test.zip", "test1.txt", ExtractFileOptions{
Folder: testArchiveBaseDir + "/extracted/zip",
})
assert.NoError(t, err)
assert.FileExists(t, testArchiveBaseDir+"/extracted/zip/test1.txt")
t.Log("== ExtractTar ==") t.Log("== ExtractTar ==")
err = Extract(testArchiveBaseDir+"/test.tar", ExtractOptions{ err = Extract(testArchiveBaseDir+"/test.tar", ExtractOptions{
Folder: testArchiveBaseDir + "/extracted/tar", Folder: testArchiveBaseDir + "/extracted/tar",
}) })
assert.NoError(t, err) assert.NoError(t, err)
err = os.RemoveAll(testArchiveBaseDir + "/extracted/tar")
assert.NoError(t, err)
t.Log("== ExtractFileTar ==")
err = ExtractFile(testArchiveBaseDir+"/test.tar", "test1.txt", ExtractFileOptions{
Folder: testArchiveBaseDir + "/extracted/tar",
})
assert.NoError(t, err)
assert.FileExists(t, testArchiveBaseDir+"/extracted/tar/test1.txt")
t.Log("== ExtractTarXz ==") t.Log("== ExtractTarXz ==")
err = Extract(testArchiveBaseDir+"/test.tar.xz", ExtractOptions{ err = Extract(testArchiveBaseDir+"/test.tar.xz", ExtractOptions{
Folder: testArchiveBaseDir + "/extracted/xz", Folder: testArchiveBaseDir + "/extracted/xz",
}) })
assert.NoError(t, err) assert.NoError(t, err)
err = os.RemoveAll(testArchiveBaseDir + "/extracted/xz")
assert.NoError(t, err)
t.Log("== ExtractFileTarXz ==")
err = ExtractFile(testArchiveBaseDir+"/test.tar.xz", "test1.txt", ExtractFileOptions{
Folder: testArchiveBaseDir + "/extracted/xz",
})
assert.NoError(t, err)
assert.FileExists(t, testArchiveBaseDir+"/extracted/xz/test1.txt")
t.Log("== ExtractTarBz ==") t.Log("== ExtractTarBz ==")
err = Extract(testArchiveBaseDir+"/test.tar.bz2", ExtractOptions{ err = Extract(testArchiveBaseDir+"/test.tar.bz2", ExtractOptions{
Folder: testArchiveBaseDir + "/extracted/bzip", Folder: testArchiveBaseDir + "/extracted/bzip",
}) })
assert.NoError(t, err) assert.NoError(t, err)
err = os.RemoveAll(testArchiveBaseDir + "/extracted/bzip")
assert.NoError(t, err)
t.Log("== ExtractFileTarBz ==")
err = ExtractFile(testArchiveBaseDir+"/test.tar.bz2", "test1.txt", ExtractFileOptions{
Folder: testArchiveBaseDir + "/extracted/bzip",
})
assert.NoError(t, err)
assert.FileExists(t, testArchiveBaseDir+"/extracted/bzip/test1.txt")
t.Log("== ExtractTarGz ==") t.Log("== ExtractTarGz ==")
err = Extract(testArchiveBaseDir+"/test.tar.gz", ExtractOptions{ err = Extract(testArchiveBaseDir+"/test.tar.gz", ExtractOptions{
Folder: testArchiveBaseDir + "/extracted/gz", Folder: testArchiveBaseDir + "/extracted/gz",
}) })
assert.NoError(t, err) assert.NoError(t, err)
err = os.RemoveAll(testArchiveBaseDir + "/extracted/gz")
assert.NoError(t, err)
t.Log("== ExtractFileTarGz ==")
err = ExtractFile(testArchiveBaseDir+"/test.tar.gz", "test1.txt", ExtractFileOptions{
Folder: testArchiveBaseDir + "/extracted/gz",
})
assert.NoError(t, err)
assert.FileExists(t, testArchiveBaseDir+"/extracted/gz/test1.txt")
err = os.RemoveAll(testArchiveBaseDir + "/extracted") err = os.RemoveAll(testArchiveBaseDir + "/extracted")
assert.NoError(t, err) assert.NoError(t, err)

2
go.mod
View file

@ -1,4 +1,4 @@
module egtyl.xyz/omnibill/archiver module egtyl.xyz/shane/archiver
go 1.23.2 go 1.23.2

24
open.go
View file

@ -69,6 +69,30 @@ func Extract(path string, options ExtractOptions) error {
return nil return nil
} }
// ExtractFile opens an archive file and extracts a specific file within the archive.
// It takes a path, a file path, and ExtractFileOptions for its parameters.
// The function returns an error, if any.
func ExtractFile(path string, file string, options ExtractFileOptions) error {
archive, err := Open(path)
if err != nil {
return err
}
defer archive.Close()
archiveFile, err := archive.GetFile(file)
if err != nil {
return err
}
if err := archiveFile.Extract(options); err != nil {
return err
}
if err := archive.Close(); err != nil {
return err
}
return nil
}
func openArchive(filesystem Filesystem, path string) (*Archive, error) { func openArchive(filesystem Filesystem, path string) (*Archive, error) {
archive := new(Archive) archive := new(Archive)
archive.files = make(map[string]*File) archive.files = make(map[string]*File)