89 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			89 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // packer - a simple CLI tool to find and zip file corresponding to a given regex
 | |
| // find + zip linux CLI works too
 | |
| package main
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"github.com/akamensky/argparse"
 | |
| 	"log"
 | |
| 	"os"
 | |
| 	fp "path/filepath"
 | |
| 	re "regexp"
 | |
| )
 | |
| 
 | |
| // parseArguments - get needed arguments to launch the `packer`
 | |
| // returns 3 strings :
 | |
| // * regex
 | |
| // * outputPath
 | |
| // * directory
 | |
| func parseArguments() (string, string, string, error) {
 | |
| 	parser := argparse.NewParser("packer", "packer - zip file where filenames match with a regex")
 | |
| 	var err error
 | |
| 
 | |
| 	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)"})
 | |
| 	directory := parser.String("d", "directory", &argparse.Options{Required: false, Help: "root directory to check files", Default: "."})
 | |
| 
 | |
| 	parseError := parser.Parse(os.Args)
 | |
| 	if parseError != nil {
 | |
| 		err = fmt.Errorf("parsing error: %s", parseError)
 | |
| 	}
 | |
| 
 | |
| 	return *regex, *directory, *outputPath, err
 | |
| }
 | |
| 
 | |
| // buildRegex - build POSIX regex from a string
 | |
| // WARN: lookahead and lookbehind are not supported
 | |
| func buildRegex(regex string) (*re.Regexp, error) {
 | |
| 	rc, err := re.CompilePOSIX(regex)
 | |
| 	return rc, err
 | |
| }
 | |
| 
 | |
| // walkFilteredDir - walk into a directory and its subdirectories and find files that match a regex
 | |
| func walkDirFiltered(directory string, regex re.Regexp) ([]string, error) {
 | |
| 	var files []string
 | |
| 	err := fp.Walk(directory,
 | |
| 		func(path string, info os.FileInfo, err error) error {
 | |
| 			if err != nil {
 | |
| 				return err
 | |
| 			}
 | |
| 			if !info.IsDir() && regex.MatchString(path) {
 | |
| 				fmt.Println(path)
 | |
| 				files = append(files, path)
 | |
| 			}
 | |
| 			return err
 | |
| 		})
 | |
| 	return files, err
 | |
| }
 | |
| 
 | |
| // getFilesFromDirectoryPath - wrapper calling `walkDirFiltered()`
 | |
| func getFilesFromDirectoryPath(directory string, regex re.Regexp) ([]string, error) {
 | |
| 	files, err := walkDirFiltered(directory, regex)
 | |
| 	return files, err
 | |
| }
 | |
| 
 | |
| func main() {
 | |
| 
 | |
| 	// parse arguments
 | |
| 	regex, directory, outputPath, err := parseArguments()
 | |
| 	if err != nil {
 | |
| 		log.Fatal("error while parsing args : ", err)
 | |
| 	}
 | |
| 
 | |
| 	// build regex from string
 | |
| 	rc, err := buildRegex(regex)
 | |
| 	if err != nil {
 | |
| 		log.Fatal("error while compiling regex : '", regex, "'\nWARN: lookahead and lookbehind not implemented")
 | |
| 	}
 | |
| 
 | |
| 	// deferencing Regexp pointer
 | |
| 	rd := *rc
 | |
| 
 | |
| 	// walk into directory
 | |
| 	log.Printf("looking for file '%s' in '%s' ...", rd.String(), directory)
 | |
| 	files, err := getFilesFromDirectoryPath(directory, rd)
 | |
| 
 | |
| 	log.Printf("files found : %d", len(files))
 | |
| 	log.Printf("files zipped in %s", outputPath)
 | |
| }
 | 
