Makefile: add pickrand
[cmccabe-bin] / recursive_decompress.go
1 package main
2
3 import (
4         "flag"
5         "os/exec"
6         "path/filepath"
7         "fmt"
8         "os"
9         "strings"
10 )
11
12 var removeArchives *bool
13
14 func processPath(curPath string) error {
15         info, err := os.Stat(curPath)
16         if err != nil {
17                 return fmt.Errorf("Unable to stat %s: %s", curPath, err.Error())
18         }
19         if info.IsDir() {
20                 entries, err := os.ReadDir(curPath)
21                 if err != nil {
22                         return fmt.Errorf("Unable to call readdir on %s: %s", curPath, err.Error())
23                 }
24                 for i := range(entries) {
25                         err := processPath(filepath.Join(curPath, entries[i].Name()))
26                         if err != nil {
27                                 return err
28                         }
29                 }
30         } else {
31                 extractedBaseName, err := extractIfPossible(curPath)
32                 if err != nil {
33                         return err
34                 }
35                 if extractedBaseName != "" {
36                         err = processPath(filepath.Join(filepath.Dir(curPath), extractedBaseName))
37                         if err != nil {
38                                 return err
39                         }
40                         if *removeArchives {
41                                 err = os.Remove(curPath)
42                                 if err != nil {
43                                         return fmt.Errorf("Unable to remove archive file %s: %s", curPath, err.Error())
44                                 }
45                                 fmt.Printf("== rm %s\n", curPath)
46                         }
47                 }
48         }
49         return nil
50 }
51
52 func extractIfPossible(curPath string) (string, error) {
53         if strings.HasSuffix(curPath, ".tgz") {
54                 return extractTgz(curPath, ".tgz")
55         } else if strings.HasSuffix(curPath, ".tar.gz") {
56                 return extractTgz(curPath, ".tar.gz")
57         } else if strings.HasSuffix(curPath, ".7z") {
58                 return extract7z(curPath)
59         } else if strings.HasSuffix(curPath, ".zip") {
60                 return extractZip(curPath)
61         }
62         return "", nil
63 }
64
65 func extractTgz(curPath string, suffix string) (string, error) {
66         fmt.Printf("== decompressing tar file %s\n", curPath)
67         cmd := exec.Command("tar", "xvf", filepath.Base(curPath))
68         cmd.Dir = filepath.Dir(curPath)
69         //cmd.Stdout = os.Stdout
70         err := cmd.Run()
71         if err != nil {
72                 return "", fmt.Errorf("error running tar xvf on %s: %s", curPath, err.Error())
73         }
74         return filepath.Base(curPath[:len(curPath) - len(suffix)]), nil
75 }
76
77 func extract7z(curPath string) (string, error) {
78         fmt.Printf("== decompressing 7z file %s\n", curPath)
79         extractedBaseName := curPath[:len(curPath) - len(".7z")]
80         err := os.Mkdir(extractedBaseName, 0755)
81         if err != nil {
82                 return "", fmt.Errorf("unable to mkdir '%s': %s", extractedBaseName, err.Error())
83         }
84         absCurPath, err := filepath.Abs(curPath)
85         if err != nil {
86                 return "", fmt.Errorf("unable to get absolute path for '%s': %s", curPath, err.Error())
87         }
88         absExtractedBaseName, err := filepath.Abs(extractedBaseName)
89         if err != nil {
90                 return "", fmt.Errorf("unable to get absolute path for '%s': %s", extractedBaseName, err.Error())
91         }
92         cmd := exec.Command("7z", "x", absCurPath)
93         cmd.Dir = absExtractedBaseName
94         //cmd.Stdout = os.Stdout
95         err = cmd.Run()
96         if err != nil {
97                 return "", fmt.Errorf("error running 7z on %s: %s", curPath, err.Error())
98         }
99         return extractedBaseName, nil
100 }
101
102 func extractZip(curPath string) (string, error) {
103         fmt.Printf("== decompressing zip file %s\n", curPath)
104         extractedBaseName := curPath[:len(curPath) - len(".zip")]
105         err := os.Mkdir(extractedBaseName, 0755)
106         if err != nil {
107                 return "", fmt.Errorf("unable to mkdir '%s': %s", extractedBaseName, err.Error())
108         }
109         absCurPath, err := filepath.Abs(curPath)
110         if err != nil {
111                 return "", fmt.Errorf("unable to get absolute path for '%s': %s", curPath, err.Error())
112         }
113         absExtractedBaseName, err := filepath.Abs(extractedBaseName)
114         if err != nil {
115                 return "", fmt.Errorf("unable to get absolute path for '%s': %s", extractedBaseName, err.Error())
116         }
117         cmd := exec.Command("unzip", absCurPath)
118         cmd.Dir = absExtractedBaseName
119         //cmd.Stdout = os.Stdout
120         err = cmd.Run()
121         if err != nil {
122                 return "", fmt.Errorf("error running unzip on %s: %s", curPath, err.Error())
123         }
124         return extractedBaseName, nil
125 }
126
127 func main() {
128         removeArchives = flag.Bool("r", false, "Remove archive files after decompressing them")
129         flag.Usage = func() {
130                 fmt.Printf("recursive_decompress: recursively decompresses a path.\n")
131                 fmt.Printf("usage: recursive_decompress [flags] [paths...]\n")
132                 fmt.Printf("\n")
133                 flag.PrintDefaults()
134         }
135         flag.Parse()
136         curPath := "."
137         if flag.Arg(0) != "" {
138                 curPath = flag.Arg(0)
139         }
140         err := processPath(curPath)
141         if err != nil {
142                 fmt.Printf("error: %s\n", err.Error())
143                 os.Exit(1)
144         }
145         os.Exit(0)
146 }