|
7 | 7 | _ "embed"
|
8 | 8 | "flag"
|
9 | 9 | "fmt"
|
| 10 | + "io" |
10 | 11 | "os"
|
11 | 12 | "runtime"
|
12 | 13 | "strings"
|
@@ -64,7 +65,7 @@ func main() {
|
64 | 65 | aliasU := flag.Bool("p", false, "alias for noprint")
|
65 | 66 | aliasV := flag.Bool("v", false, "alias for version")
|
66 | 67 | flag.Usage = func() {
|
67 |
| - help(true) |
| 68 | + help(os.Stderr, true) |
68 | 69 | }
|
69 | 70 | flag.Parse()
|
70 | 71 | flags(ver, aliasV, aliasQ)
|
@@ -106,142 +107,143 @@ func flags(ver, aliasV, quiet *bool) {
|
106 | 107 | showLogo := !*quiet
|
107 | 108 | switch strings.ToLower(arg) {
|
108 | 109 | case "-h", "-help", "--help":
|
109 |
| - help(showLogo) |
| 110 | + help(os.Stderr, showLogo) |
110 | 111 | os.Exit(0)
|
111 | 112 | case "-v", "-version", "--version":
|
112 |
| - info(quiet) |
| 113 | + info(os.Stdout, quiet) |
113 | 114 | os.Exit(0)
|
114 | 115 | }
|
115 | 116 | }
|
116 | 117 | // print version information
|
117 | 118 | if *ver || *aliasV {
|
118 |
| - info(quiet) |
| 119 | + info(os.Stdout, quiet) |
119 | 120 | os.Exit(0)
|
120 | 121 | }
|
121 | 122 | // print help if no arguments are given
|
| 123 | + w := os.Stderr |
122 | 124 | if len(flag.Args()) == 0 {
|
| 125 | + s := "zipcmt requires at least one directory to scan" |
123 | 126 | if runtime.GOOS == winOS {
|
124 |
| - fmt.Fprintln(os.Stderr, color.Warn.Sprint("zipcmt requires at least one directory or drive letter to scan")) |
125 |
| - } else { |
126 |
| - fmt.Fprintln(os.Stderr, color.Warn.Sprint("zipcmt requires at least one directory to scan")) |
| 127 | + s = "zipcmt requires at least one directory or drive letter to scan" |
127 | 128 | }
|
128 |
| - fmt.Fprintln(os.Stderr) |
129 |
| - help(false) |
| 129 | + fmt.Fprintln(w, color.Warn.Sprint(s)+"\n") |
| 130 | + help(w, false) |
130 | 131 | os.Exit(0)
|
131 | 132 | }
|
132 | 133 | }
|
133 | 134 |
|
134 |
| -func helpPosix() { |
| 135 | +func helpPosix(w io.Writer) { |
135 | 136 | const ps = string(os.PathSeparator)
|
136 |
| - fmt.Fprintln(os.Stderr, " zipcmt [options] <directories>") |
137 |
| - fmt.Fprintln(os.Stderr, "") |
138 |
| - fmt.Fprintln(os.Stderr, "Examples:") |
139 |
| - fmt.Fprint(os.Stderr, color.Info.Sprint(" zipcmt .\t\t\t\t")) |
140 |
| - fmt.Fprintln(os.Stderr, |
| 137 | + fmt.Fprintln(w, " zipcmt [options] <directories>") |
| 138 | + fmt.Fprintln(w, "") |
| 139 | + fmt.Fprintln(w, "Examples:") |
| 140 | + fmt.Fprint(w, color.Info.Sprint(" zipcmt .\t\t\t\t")) |
| 141 | + fmt.Fprintln(w, |
141 | 142 | color.Note.Sprint("# scan the current directory and subdirectories for unique comments"))
|
142 |
| - fmt.Fprint(os.Stderr, color.Info.Sprintf(" zipcmt -save=~%stext ~%sDownloads\t", ps, ps)) |
143 |
| - fmt.Fprintln(os.Stderr, |
144 |
| - color.Note.Sprint("# scan the user download directories and save unique comments to a directory")) |
145 |
| - fmt.Fprint(os.Stderr, color.Info.Sprintf(" zipcmt -a -s=~%stext ~%sDownloads\t", ps, ps)) |
146 |
| - fmt.Fprintln(os.Stderr, |
147 |
| - color.Note.Sprint("# scan the user download directories and save all comments to a directory")) |
148 |
| - fmt.Fprint(os.Stderr, color.Info.Sprintf(" zipcmt -quiet %s | less\t\t", ps)) |
149 |
| - fmt.Fprintln(os.Stderr, |
| 143 | + fmt.Fprint(w, color.Info.Sprintf(" zipcmt -save=~%swork ~%sDownloads\t", ps, ps)) |
| 144 | + fmt.Fprintln(w, |
| 145 | + color.Note.Sprint("# scan the user downloads directory, then save unique comments to a directory")) |
| 146 | + fmt.Fprint(w, color.Info.Sprintf(" zipcmt -a -s=~%swork ~%sDownloads\t", ps, ps)) |
| 147 | + fmt.Fprintln(w, |
| 148 | + color.Note.Sprint("# scan the user downloads directory, then save all comments to a directory")) |
| 149 | + fmt.Fprint(w, color.Info.Sprintf(" zipcmt -quiet %s | less\t\t", ps)) |
| 150 | + fmt.Fprintln(w, |
150 | 151 | color.Note.Sprint("# scan the whole system to view the unique comments in a page reader"))
|
151 | 152 | }
|
152 | 153 |
|
153 |
| -func helpWin() { |
| 154 | +func helpWin(w io.Writer) { |
154 | 155 | const ps = string(os.PathSeparator)
|
155 |
| - fmt.Fprintln(os.Stderr, " zipcmt [options] <directories or drive letters>") |
156 |
| - fmt.Fprintln(os.Stderr, "") |
157 |
| - fmt.Fprintln(os.Stderr, "Examples:") |
158 |
| - fmt.Fprint(os.Stderr, color.Info.Sprint(" zipcmt .\t\t\t")) |
159 |
| - fmt.Fprintln(os.Stderr, |
| 156 | + fmt.Fprintln(w, " zipcmt [options] <directories or drive letters>") |
| 157 | + fmt.Fprintln(w, "") |
| 158 | + fmt.Fprintln(w, "Examples:") |
| 159 | + fmt.Fprint(w, color.Info.Sprint(" zipcmt .\t\t\t")) |
| 160 | + fmt.Fprintln(w, |
160 | 161 | color.Note.Sprint("# scan the current directory and subdirectories for unique comments"))
|
161 | 162 | if hd, err := os.UserHomeDir(); err == nil {
|
162 |
| - fmt.Fprintln(os.Stderr, color.Info.Sprintf(" zipcmt -save=C:\\text %s%sDownloads\t\t", hd, ps)) |
163 |
| - fmt.Fprintln(os.Stderr, color.Note.Sprint("\t\t\t\t# scan the files and directories in Downloads"+ |
164 |
| - " and save the unique comments to 'C:\\text'")) |
165 |
| - } |
166 |
| - fmt.Fprint(os.Stderr, color.Info.Sprint(" zipcmt -save=C:\\text C:\t")) |
167 |
| - fmt.Fprintln(os.Stderr, |
168 |
| - color.Note.Sprint("# scan the 'C' drive and save the unique comments to the 'C:\\text' directory")) |
169 |
| - fmt.Fprint(os.Stderr, color.Info.Sprint(" zipcmt -quiet C: D: | more\t")) |
170 |
| - fmt.Fprintln(os.Stderr, |
| 163 | + fmt.Fprintln(w, color.Info.Sprintf(" zipcmt -save=C:\\work %s%sDownloads\t\t", hd, ps)) |
| 164 | + fmt.Fprintln(w, color.Note.Sprint("\t\t\t\t# scan the files and directories in Downloads"+ |
| 165 | + " and save the unique comments to 'C:\\work'")) |
| 166 | + } |
| 167 | + fmt.Fprint(w, color.Info.Sprint(" zipcmt -save=C:\\work C:\t")) |
| 168 | + fmt.Fprintln(w, |
| 169 | + color.Note.Sprint("# scan the 'C' drive and save the unique comments to the 'C:\\work' directory")) |
| 170 | + fmt.Fprint(w, color.Info.Sprint(" zipcmt -quiet C: D: | more\t")) |
| 171 | + fmt.Fprintln(w, |
171 | 172 | color.Note.Sprint("# scan the 'C' and 'D' drives to view the unique comments in a page reader"))
|
172 | 173 | }
|
173 | 174 |
|
174 | 175 | // Help, usage and examples.
|
175 |
| -func help(logo bool) { |
| 176 | +func help(w io.Writer, logo bool) { |
176 | 177 | var f *flag.Flag
|
177 | 178 | if logo {
|
178 |
| - fmt.Fprintln(os.Stderr, brand) |
179 |
| - fmt.Fprint(os.Stderr, " Zip Comment is the super-fast batch, zip file comment viewer, and extractor.\n"+ |
180 |
| - " Using a modern PC with the zip files stored on a solid-state drive,\n"+ |
181 |
| - " zipcmt handles many thousands of archives per second.\n\n") |
| 179 | + fmt.Fprintln(w, brand) |
| 180 | + fmt.Fprint(w, " Zip Comment is the super-fast, batch zip file-comment viewer and extractor.\n"+ |
| 181 | + " Using a modern PC, zipcmt handles many thousands of archives per second.\n\n") |
182 | 182 | }
|
183 |
| - fmt.Fprintln(os.Stderr, "Usage:") |
| 183 | + fmt.Fprintln(w, "Usage:") |
184 | 184 | if runtime.GOOS == winOS {
|
185 |
| - helpWin() |
| 185 | + helpWin(w) |
186 | 186 | } else {
|
187 |
| - helpPosix() |
| 187 | + helpPosix(w) |
188 | 188 | }
|
189 |
| - fmt.Fprintln(os.Stderr, "") |
190 |
| - fmt.Fprintln(os.Stderr, "Options:") |
| 189 | + fmt.Fprintln(w, "") |
| 190 | + fmt.Fprintln(w, "Options:") |
191 | 191 | const padding = 4
|
192 |
| - w := tabwriter.NewWriter(os.Stderr, 0, 0, padding, ' ', 0) |
| 192 | + tw := tabwriter.NewWriter(w, 0, 0, padding, ' ', 0) |
193 | 193 | f = flag.Lookup("save")
|
194 |
| - fmt.Fprintf(w, " -%v, -%v=DIRECTORY\t%v\n", "s", f.Name, f.Usage) |
| 194 | + fmt.Fprintf(tw, " -%v, -%v=DIRECTORY\t%v\n", "s", f.Name, f.Usage) |
195 | 195 | f = flag.Lookup("overwrite")
|
196 |
| - fmt.Fprintf(w, " -%v, -%v\t%v\n", f.Name[:1], f.Name, f.Usage) |
| 196 | + fmt.Fprintf(tw, " -%v, -%v\t%v\n", f.Name[:1], f.Name, f.Usage) |
197 | 197 | f = flag.Lookup("noprint")
|
198 |
| - fmt.Fprintf(w, " -p, -%v\t%v\n", f.Name, f.Usage) |
199 |
| - fmt.Fprintln(w, " \t") |
| 198 | + fmt.Fprintf(tw, " -p, -%v\t%v\n", f.Name, f.Usage) |
| 199 | + fmt.Fprintln(tw, " \t") |
200 | 200 | f = flag.Lookup("norecursive")
|
201 |
| - fmt.Fprintf(w, " -%v, -%v\t%v\n", "r", f.Name, f.Usage) |
| 201 | + fmt.Fprintf(tw, " -%v, -%v\t%v\n", "r", f.Name, f.Usage) |
202 | 202 | f = flag.Lookup("all")
|
203 |
| - fmt.Fprintf(w, " -%v, -%v\t%v\n", f.Name[:1], f.Name, f.Usage) |
| 203 | + fmt.Fprintf(tw, " -%v, -%v\t%v\n", f.Name[:1], f.Name, f.Usage) |
204 | 204 | f = flag.Lookup("now")
|
205 |
| - fmt.Fprintf(w, " -%v\t%v\n", f.Name, f.Usage) |
| 205 | + fmt.Fprintf(tw, " -%v\t%v\n", f.Name, f.Usage) |
206 | 206 | f = flag.Lookup("raw")
|
207 |
| - fmt.Fprintf(w, " -%v\t%v\n", f.Name, f.Usage) |
208 |
| - fmt.Fprintln(w, " \t") |
| 207 | + fmt.Fprintf(tw, " -%v\t%v\n", f.Name, f.Usage) |
| 208 | + fmt.Fprintln(tw, " \t") |
209 | 209 | f = flag.Lookup("export")
|
210 |
| - fmt.Fprintf(w, " -%v\t%v\n", f.Name, f.Usage) |
211 |
| - fmt.Fprintln(w, " \t") |
| 210 | + fmt.Fprintf(tw, " -%v\t%v\n", f.Name, f.Usage) |
| 211 | + fmt.Fprintln(tw, " \t") |
212 | 212 | f = flag.Lookup("quiet")
|
213 |
| - fmt.Fprintf(w, " -%v, -%v\t%v\n", f.Name[:1], f.Name, f.Usage) |
| 213 | + fmt.Fprintf(tw, " -%v, -%v\t%v\n", f.Name[:1], f.Name, f.Usage) |
214 | 214 | f = flag.Lookup("version")
|
215 |
| - fmt.Fprintf(w, " -%v, -%v\t%v\n", f.Name[:1], f.Name, f.Usage) |
216 |
| - fmt.Fprintln(w, " -h, -help\tshow this list of options") |
217 |
| - fmt.Fprintln(w) |
218 |
| - optimial(w) |
219 |
| - w.Flush() |
| 215 | + fmt.Fprintf(tw, " -%v, -%v\t%v\n", f.Name[:1], f.Name, f.Usage) |
| 216 | + fmt.Fprintln(tw, " -h, -help\tshow this list of options") |
| 217 | + fmt.Fprintln(tw) |
| 218 | + optimial(tw) |
| 219 | + tw.Flush() |
220 | 220 | }
|
221 | 221 |
|
222 |
| -func optimial(w *tabwriter.Writer) { |
223 |
| - if runtime.GOOS == winOS { |
224 |
| - fmt.Fprintln(w, "For optimal performance Windows users may wish to temporarily disable"+ |
225 |
| - " the Virus & threat 'Real-time protection' under Windows Security.") |
226 |
| - fmt.Fprintln(w, "Or create Windows Security Exclusions for the directories to be scanned.") |
227 |
| - fmt.Fprintln(w, "https://support.microsoft.com/en-us/windows/"+ |
228 |
| - "add-an-exclusion-to-windows-security-811816c0-4dfd-af4a-47e4-c301afe13b26") |
| 222 | +func optimial(tw *tabwriter.Writer) { |
| 223 | + if runtime.GOOS != winOS { |
| 224 | + return |
229 | 225 | }
|
| 226 | + fmt.Fprintln(tw, "For optimal performance Windows users may wish to temporarily disable"+ |
| 227 | + " the Virus & threat 'Real-time protection' under Windows Security.") |
| 228 | + fmt.Fprintln(tw, "Or create Windows Security Exclusions for the directories to be scanned.") |
| 229 | + fmt.Fprintln(tw, "https://support.microsoft.com/en-us/windows/"+ |
| 230 | + "add-an-exclusion-to-windows-security-811816c0-4dfd-af4a-47e4-c301afe13b26") |
230 | 231 | }
|
231 | 232 |
|
232 | 233 | // Info prints out the program information and version.
|
233 |
| -func info(quiet *bool) { |
| 234 | +func info(w io.Writer, quiet *bool) { |
234 | 235 | const copyright = "\u00A9"
|
235 | 236 | if !*quiet {
|
236 |
| - fmt.Fprintln(os.Stdout, brand) |
| 237 | + fmt.Fprintln(w, brand) |
237 | 238 | }
|
238 |
| - fmt.Fprintf(os.Stdout, "zipcmt v%s\n%s 2021-24 Ben Garrett, logo by sensenstahl\n", version, copyright) |
239 |
| - fmt.Fprintf(os.Stdout, "https://github.com/bengarrett/zipcmt\n\n") |
240 |
| - fmt.Fprintf(os.Stdout, "build: %s (%s)\n", commit, date) |
| 239 | + fmt.Fprintf(w, "zipcmt v%s\n%s 2021-24 Ben Garrett, logo by sensenstahl\n", |
| 240 | + version, copyright) |
| 241 | + fmt.Fprintf(w, "https://github.com/bengarrett/zipcmt\n\n") |
| 242 | + fmt.Fprintf(w, "build: %s (%s)\n", commit, date) |
241 | 243 | exe, err := misc.Self()
|
242 | 244 | if err != nil {
|
243 |
| - fmt.Fprintf(os.Stdout, "path: %s\n", err) |
| 245 | + fmt.Fprintf(w, "path: %s\n", err) |
244 | 246 | return
|
245 | 247 | }
|
246 |
| - fmt.Fprintf(os.Stdout, "path: %s\n", exe) |
| 248 | + fmt.Fprintf(w, "path: %s\n", exe) |
247 | 249 | }
|
0 commit comments