implement WritterError + add arg to remove files after zip
This commit is contained in:
parent
ca0b717a02
commit
ad4c4220f5
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,4 +1,6 @@
|
|||||||
# binary file
|
# binary file
|
||||||
packer
|
packer
|
||||||
# zip file
|
# zip file
|
||||||
*.zip
|
*.zip
|
||||||
|
# test folder
|
||||||
|
test
|
||||||
97
main.go
97
main.go
@ -1,9 +1,11 @@
|
|||||||
// packer - a simple CLI tool to find and zip file corresponding to a given regex
|
// packer - a simple CLI tool to find and zip file corresponding to a given regex
|
||||||
|
// the archive keeps the folder structure
|
||||||
// find + zip linux CLI works too
|
// find + zip linux CLI works too
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"archive/zip"
|
"archive/zip"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/akamensky/argparse"
|
"github.com/akamensky/argparse"
|
||||||
"io"
|
"io"
|
||||||
@ -13,25 +15,45 @@ import (
|
|||||||
re "regexp"
|
re "regexp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// WritterError
|
||||||
|
// Useless, just to play with `errors.As()` to check specific error
|
||||||
|
type WritterError struct {
|
||||||
|
message error
|
||||||
|
}
|
||||||
|
|
||||||
|
type ErrorCode interface {
|
||||||
|
Code() int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (we WritterError) Error() string {
|
||||||
|
return fmt.Sprintf("error occured while creating archive : %s", we.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (we WritterError) Code() int {
|
||||||
|
return 500
|
||||||
|
}
|
||||||
|
|
||||||
// parseArguments - get needed arguments to launch the `packer`
|
// parseArguments - get needed arguments to launch the `packer`
|
||||||
// returns 3 strings :
|
// returns 3 strings :
|
||||||
// * regex
|
// * regex
|
||||||
// * outputPath
|
// * outputPath - full path of the zip archive
|
||||||
// * directory
|
// * directory - which directory to check
|
||||||
func parseArguments() (string, string, string, error) {
|
// * remove - delete all file after creating zip archive
|
||||||
|
func parseArguments() (string, string, string, bool, error) {
|
||||||
parser := argparse.NewParser("packer", "packer - zip file where filenames match with a regex")
|
parser := argparse.NewParser("packer", "packer - zip file where filenames match with a regex")
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
regex := parser.String("r", "regex", &argparse.Options{Required: true, Help: "filename Regex"})
|
regex := parser.String("r", "regex", &argparse.Options{Required: true, Help: "filename Regex"})
|
||||||
outputPath := parser.String("o", "output-path", &argparse.Options{Required: true, Help: "zip output path (including zip name)"})
|
outputPath := parser.String("o", "output-path", &argparse.Options{Required: true, Help: "zip output path (including zip name)"})
|
||||||
directory := parser.String("d", "directory", &argparse.Options{Required: false, Help: "root directory to check files", Default: "."})
|
directory := parser.String("d", "directory", &argparse.Options{Required: false, Help: "root directory to check files", Default: "."})
|
||||||
|
remove := parser.Flag("x", "remove", &argparse.Options{Required: false, Help: "remove files after archive creation", Default: false})
|
||||||
|
|
||||||
parseError := parser.Parse(os.Args)
|
parseError := parser.Parse(os.Args)
|
||||||
if parseError != nil {
|
if parseError != nil {
|
||||||
err = fmt.Errorf("parsing error: %s", parseError)
|
err = fmt.Errorf("parsing error: %s", parseError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return *regex, *directory, *outputPath, err
|
return *regex, *directory, *outputPath, *remove, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// buildRegex - build POSIX regex from a string
|
// buildRegex - build POSIX regex from a string
|
||||||
@ -71,7 +93,7 @@ func writeFileContent(f *os.File, zf io.Writer) (err error) {
|
|||||||
b := make([]byte, chunkSize)
|
b := make([]byte, chunkSize)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
_, err := f.Read(b)
|
_, err = f.Read(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err != io.EOF {
|
if err != io.EOF {
|
||||||
continue
|
continue
|
||||||
@ -87,12 +109,12 @@ func writeFileContent(f *os.File, zf io.Writer) (err error) {
|
|||||||
// generateZip - create a zip archive
|
// generateZip - create a zip archive
|
||||||
// * outputPath: zip archive full path
|
// * outputPath: zip archive full path
|
||||||
// * filePaths: files path
|
// * filePaths: files path
|
||||||
func generateZip(outputPath string, filepaths []string) (err error) {
|
func generateZip(outputPath string, filepaths []string) error {
|
||||||
|
|
||||||
// create a zipfile from `outputPath`
|
// create a zipfile from `outputPath`
|
||||||
zipPath, err := os.Create(outputPath)
|
zipPath, createErr := os.Create(outputPath)
|
||||||
if err != nil {
|
if createErr != nil {
|
||||||
return err
|
return createErr
|
||||||
}
|
}
|
||||||
defer zipPath.Close()
|
defer zipPath.Close()
|
||||||
|
|
||||||
@ -101,37 +123,56 @@ func generateZip(outputPath string, filepaths []string) (err error) {
|
|||||||
|
|
||||||
for _, filepath := range filepaths {
|
for _, filepath := range filepaths {
|
||||||
// open matching regex file
|
// open matching regex file
|
||||||
f, err := os.Open(filepath)
|
f, openErr := os.Open(filepath)
|
||||||
if err != nil {
|
if openErr != nil {
|
||||||
log.Println("[ERROR] :", err)
|
log.Println("[ERROR] :", openErr)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a zipped file
|
// create a zipped file
|
||||||
zf, err := w.Create(filepath)
|
zf, zipErr := w.Create(filepath)
|
||||||
if err != nil {
|
if zipErr != nil {
|
||||||
log.Println("[ERROR] :", err)
|
log.Println("[ERROR] :", zipErr)
|
||||||
f.Close()
|
f.Close()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// write file content into zipped file
|
// write file content into zipped file
|
||||||
err = writeFileContent(f, zf)
|
writeErr := writeFileContent(f, zf)
|
||||||
|
// catch sentinel error `io.EOF`
|
||||||
|
if writeErr != nil && writeErr != io.EOF {
|
||||||
|
log.Println("[ERROR] :", writeErr)
|
||||||
|
f.Close()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
// clean up opened file
|
// clean up opened file
|
||||||
f.Close()
|
f.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure to check the error on Close.
|
// make sure to check the error on Close.
|
||||||
err = w.Close()
|
closeErr := w.Close()
|
||||||
|
if closeErr != nil {
|
||||||
|
return WritterError{message: fmt.Errorf("error occured while closing the zip archive : %w", closeErr)}
|
||||||
|
}
|
||||||
|
|
||||||
return err
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// removeFiles - can't be more obvious...
|
||||||
|
func removeFiles(filepaths []string) {
|
||||||
|
for _, filepath := range filepaths {
|
||||||
|
err := os.Remove(filepath)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("[ERROR] :", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
// parse arguments
|
// parse arguments
|
||||||
regex, directory, outputPath, err := parseArguments()
|
regex, directory, outputPath, remove, err := parseArguments()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("error while parsing args : ", err)
|
log.Fatal("error while parsing args : ", err)
|
||||||
}
|
}
|
||||||
@ -151,7 +192,23 @@ func main() {
|
|||||||
|
|
||||||
// generating zip archive
|
// generating zip archive
|
||||||
log.Printf("files found : %d", len(files))
|
log.Printf("files found : %d", len(files))
|
||||||
generateZip(outputPath, files)
|
err = generateZip(outputPath, files)
|
||||||
|
|
||||||
|
// check if errors occured during zip
|
||||||
|
var errorCode interface {
|
||||||
|
Code() int
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
if errors.As(err, &errorCode) {
|
||||||
|
log.Fatal("zip archive writing error : ", err)
|
||||||
|
}
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if remove {
|
||||||
|
log.Printf("clean up archive files...")
|
||||||
|
removeFiles(files)
|
||||||
|
}
|
||||||
|
|
||||||
log.Printf("zip archive generated in %s", outputPath)
|
log.Printf("zip archive generated in %s", outputPath)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user